如何正确使用 EFCore 和 SignalR Core(避免缓存实体)

How to properly use EFCore with SignalR Core (avoid caching entities)

我刚刚发现了一些非常奇怪的行为,事实证明它一点也不奇怪。

我的 select 语句(从数据库查询)只在第一次工作。第二次,缓存了来自数据库的查询。

Inside Hub 方法我每 10 秒从数据库中读取一些内容,并且 return 结果发送给所有连接的客户端。但是,如果某些 API 更改此数据,Hub 上下文不会读取实际数据。

this 线程中我发现了这个:

When you use EF it by default loads each entity only once per context. The first query creates entity instance and stores it internally. Any subsequent query which requires entity with the same key returns this stored instance. If values in the data store changed you still receive the entity with values from the initial query. This is called Identity map pattern. You can force the object context to reload the entity but it will reload a single shared instance.

所以我的问题是如何在 SignalR Core 集线器方法中正确使用 EFCore?

我可以使用 AsNoTracking,但我想使用一些全局设置。开发人员很容易忘记添加 AsNoTracking,这可能意味着向用户提供过时的数据。

我想在 BaseHub class 中编写一些代码,告诉上下文不要跟踪数据。如果我更改实体属性,SaveChanges 应该更新数据。这可以实现吗?从hub方式查询时,很难一直想着加AsNoTracking

I would like to write some code in my BaseHub class which will tell context do not track data.

默认查询跟踪行为由 ChangeTracker.QueryTrackingBehavior 属性 控制,默认值为 TrackAll(即跟踪)。

您可以将其更改为 NoTracking,然后将 AsTracking() 用于需要跟踪的查询。这是一个更普遍需要的问题。

If I change entity properties, SaveChanges should update data.

如果实体未被跟踪,这是不可能的。

如果您真的想要 tracking 使用 "database wins" 策略的查询,恐怕目前在 EF Core 中是不可能的。我认为 EF6 对象上下文服务有一个选项用于指定 "client wins" 与 "database wins" 策略,但 EF Core 目前不提供此类控制并且始终实施 "client wins" 策略。