【问题标题】:How to properly use EFCore with SignalR Core (avoid caching entities)如何正确使用 EFCore 和 SignalR Core(避免缓存实体)
【发布时间】:2018-08-22 08:48:11
【问题描述】:

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

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

在 Hub 方法中,我每 10 秒从数据库中读取一些内容并将结果返回给所有连接的客户端。但是如果某些 API 更改了这些数据,Hub 上下文不会读取实际数据。

this 线程中我发现了这个:

当您使用 EF 时,默认情况下每个上下文仅加载每个实体一次。第一个查询创建实体实例并将其存储在内部。任何需要具有相同键的实体的后续查询都会返回此存储的实例。如果数据存储中的值发生更改,您仍然会收到带有初始查询值的实体。这称为身份映射模式。您可以强制对象上下文重新加载实体,但它会重新加载单个共享实例。

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

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

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

【问题讨论】:

  • DbContext 和其他范围服务可以像在 asp.net 核心控制器中一样使用。看到这个answer

标签: entity-framework signalr entity-framework-core asp.net-core-signalr


【解决方案1】:

我想在我的 BaseHub 类中编写一些代码,告诉上下文不要跟踪数据。

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

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

如果我更改实体属性,SaveChanges 应该更新数据。

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

如果您真的希望跟踪 使用“数据库获胜”策略的查询,恐怕目前在 EF Core 中是不可能的。我认为 EF6 对象上下文服务可以选择指定“客户端获胜”与“数据库获胜”策略,但 EF Core 目前不提供此类控制并且始终实现“客户端获胜”策略。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-31
    • 1970-01-01
    • 2010-10-25
    • 1970-01-01
    相关资源
    最近更新 更多