我刚刚发现了一些非常奇怪的行为,但事实证明它一点也不奇怪。
我的 select 语句(从数据库查询)只在第一次起作用。第二次,来自数据库的查询被缓存。
在 Hub 方法内部,我每 10 秒从数据库读取一些内容,并将结果返回给所有连接的客户端。但如果某些 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 hub 方法中正确使用 EFCore?
我可以使用AsNoTracking
,但我想使用一些全局设置。开发人员很容易忘记添加 AsNoTracking
,这可能意味着向用户提供过时的数据。
我想在我的 BaseHub
类中编写一些代码,告诉上下文不要跟踪数据。如果我更改实体属性,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.
如果实体未被跟踪,这是不可能的。
如果您确实想要使用“数据库获胜”策略来跟踪查询,恐怕目前在 EF Core 中是不可能的。我认为 EF6 对象上下文服务有一个选项用于指定“客户端获胜”与“数据库获胜”策略,但 EF Core 目前不提供此类控制,并且始终实现“客户端获胜”策略。
关于entity-framework - 如何正确使用 EFCore 和 SignalR Core(避免缓存实体),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51963039/