首页 > 解决方案 > EF Core 未在工作单元场景中跟踪正确的属性

问题描述

这个问题是我面临的问题的摘要:考虑以下问题,

我有具有以下属性的实体

public class Entity
    {
        public int Id { get; set; }
        public int Status { get; set; }
    }

状态可以是 0(新)或 1(已删除)。

我有一个服务调用,它将实体从 0 -> 1 更改为通过服务调用的。所涉及的存储库不调用 context.SaveChanges(),而是在中间件中更进一步地处理。

这看起来像:

var entity = await Context.Entities.FirstOrDefaultAsync(x => x.Id == id);

entity.SetDeleted();

SetDeleted方法将属性从 0 更改为 1。

然后,在另一个服务方法中(在同一工作单元中),读取它以检查是否存在未删除的实体。这就是问题发生的地方。

代码如下所示:

var entities = context.Entities.Any(x => x.Status != 1);

通常你会期望图表不会被返回,但不幸的是它是。奇怪的是,当您执行该ToList()函数然后运行相同的操作时,它不包括图形。这意味着,如果您有以下情况:

var entities = await Context.Entities.Where(x => x.Status!= 1).ToListAsync();
var secondFilter = entities.Where(x => x.Status != 1).ToList();

entities 包含实体,尽管它遵循相同的规则,但secondFilter 将不包含实体。

有没有人遇到过这个问题,有人知道解决方法吗?

标签: c#entity-frameworkentity-framework-core

解决方案


这是 EF 的设计行为。

当您有一个被跟踪的实体并从数据库中查询相同的实体时,被跟踪的实体永远不会被覆盖。

var entity = await Context.Entities.FirstOrDefaultAsync(x => x.Id == id);

entity.SetDeleted();

您有一个被跟踪的实体,带有一个已修改的Status.

var entities = await Context.Entities.Where(x => x.Status!= 1).ToListAsync();

运行 SQL 查询并在数据库中找到与其 Status=0相同的实体。但是,当 EF 尝试将实体添加到更改跟踪器时,它发现那里已经存在修改版本,因此它会丢弃从数据库读取的数据并将现有的修改实体添加到entities集合中。那么这个

var secondFilter = entities.Where(x => x.Status != 1).ToList();

什么都不返回,因为entityStatus=1。


推荐阅读