【问题标题】:EF Core tracking entities with same id multiple timesEF Core 多次跟踪具有相同 ID 的实体
【发布时间】:2018-08-23 09:57:04
【问题描述】:

我只是想更新客户对象的行业属性。为此,我使用存储库从数据库中检索客户端。这将导致我的行业(例如 id:149)被跟踪。

            var client = await _clientRepository.GetAsync(request.ClientId, token);
            ind = _db.ChangeTracker.Entries<Industry>().Count();

然后,我通过调用 SetIndustry 来更新行业,并使用 Id:149 的新行业(与之前相同)。

            client.SetIndustry(new Industry(149)); 
            ind = _db.ChangeTracker.Entries<Industry>().Count();

此时 EF Core 2.1 抛出异常。

System.InvalidOperationException: 'The instance of entity type 'Industry' cannot be tracked because another instance with the same key value for {'Id'} is already being tracked. When attaching existing entities, ensure that only one entity instance with a given key value is attached.

在此类中,我无法访问 DBContext,因此无法使用更改跟踪器。我想知道如何解决这个问题?

谢谢 赛博

【问题讨论】:

  • 很难给你一个好的建议,因为你对这些“存储库”有自我限制。 EF 上下文为您提供了很好的控制 - 跟踪/不跟踪查询、是否预先加载等。存储库(反)模式可能适用于简单的事情,但肯定会因关系而失败。从 EF 的角度来看,您不应使用 new Industry(149),而应使用 db.Find(149) 或类似名称。或者将 null 分配给 nav 属性并设置暴露的显式 FK 属性。
  • 实际上我们遵循 DDD 原则,我们正在使用这个存储库检索我们的聚合。同一个 repo 的 save 方法不仅仅是保存到数据库。这就是为什么我们必须这样做......
  • 我在这里怀疑 DDD - 带有参数的构造函数、SetIndustry 方法等。这只是另一个问题来源。只是不要将域模型与持久性模型混合在一起——它们有不同的要求。或者换句话说,不要使用域模型作为存储模型。创建单独的模型,在需要的地方进行两者之间的映射。商店模型不应包含任何业务/领域逻辑 - 具有公共无参数构造函数和公共自动获取/设置属性的简单 POCO 类。没有方法。没有特殊的 getter/setter。没有未映射的东西。没有 OOP。

标签: entity-framework entity-framework-core change-tracking entity-framework-core-2.1


【解决方案1】:

当我创建文档变量时,我刚刚将 AsNoTracking() 添加到我的文档对象中并且它成功了。尝试对您的客户端对象执行相同的操作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-15
    • 1970-01-01
    • 1970-01-01
    • 2020-09-19
    • 2019-08-09
    • 2019-12-07
    相关资源
    最近更新 更多