c# - 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
将不包含实体。
有没有人遇到过这个问题,有人知道解决方法吗?
解决方案
这是 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();
什么都不返回,因为entity
Status=1。
推荐阅读
- javascript - 有没有可以用于手机的全局变量?
- typescript - 打字稿:处理keyof泛型类型
- vue.js - 在nuxt中配置编译模块
- python - 如何将多维数组中的元素附加到另一个多维数组的每个元素
- python - 如何阻止 vs code 制作 .ipynb 文件?
- java - 带有额外列的多对多,但在额外列是列表的情况下分组在一起
- excel - 如何将 Datagridview 导出到 Excel 工作簿
- python-2.7 - Python2.7 错误:ImportError:没有名为 Games.Table 的模块
- mysql - MySQL UNION 查询需要时间
- c - 如何从 C 程序中的 POST/GET 方法获取数据?