自从从 .NET Framework 升级到 .NET Core 以来,我在 Entity Framework Core 中遇到了与使用
.Include()
和 .AsNoTracking()
方法相关的意外行为。
考虑以下实体:
public class Entity1
{
public int Id { get; set; }
public string Name { get; set; }
public int Entity2Id { get; set; }
public Entity2 Entity2 { get; set; }
}
public class Entity2
{
public int Id { get; set; }
public string Name { get; set; }
public ICollection<Entity1> Entity1s { get; set; }
}
当我执行查询时
Context.Entity1s.AsNoTracking().Include(x => x.Entity2)
然后尝试访问结果上的
Entity2.Entity1s
,仅显示单个元素(父元素)而不是整个列表。
但是,删除
.AsNoTracking()
会产生预期行为,显示链接到 Entity2 的 Entity1 元素的完整列表。
我试图理解为什么会出现这种差异以及为什么它在 EF Core 中表现不同。
使用
AsNoTrackingWithIdentityResolution
而不是仅使用 AsNoTracking
。
来自文档的身份解析部分:
由于跟踪查询使用更改跟踪器,因此 EF Core 在跟踪查询中进行身份解析。当具体化实体时,EF Core 会从更改跟踪器返回相同的实体实例(如果已被跟踪)。如果结果多次包含相同的实体,则每次出现时都会返回相同的实例。无跟踪查询:
- 不要使用变更跟踪器,也不进行身份解析。
- 即使结果中多次包含同一实体,也会返回实体的新实例。