我读到过一篇关于AsNoTrackingWithIdentityResolve()方法的文章,它是一种无需跟踪的身份解析方法,并且当使用它时,与上下文不同的更改跟踪器将在后台运行,以将引用同一行的实体解析为一个实例.

我试图通过运行以下代码来验证这一点,但实例并未解析为一个实例

// Initially the table is empty
Employee emp1 = new Employee()
{
    FirstName = "name1",
    LastName = "name2",
    Salary = 11111
};

context.Add(emp1);
context.SaveChanges();

Employee emp2 = (from e in context.Employees
                 where e.FirstName == "name1"
                 select e).SingleOrDefault();

// Identity resolution takes place
Console.WriteLine(emp1 == emp2); // True

Employee emp3 = (from e in context.Employees
                 where e.FirstName == "name1"
                 select e).AsNoTrackingWithIdentityResolution().SingleOrDefault();

// Expected to give True due to using AsNoTrackingWtihIdentityResolution()
Console.WriteLine(emp1 == emp3); // but found False

Employee emp4 = (from e in context.Employees
                 where e.FirstName == "name1"
                 select e).AsNoTrackingWithIdentityResolution().SingleOrDefault();

// Also no identity resolution happened
Console.WriteLine(emp4 == emp3); // False

The reference comparison only gave true when the two compared instances (which are resolved to one instance) were tracked by the context change tracker, while the other instances weren't resolved to one instance. I'm using EF core 8.0.2

所以现在:

  • 为什么在使用带有查询的AsNoTrackingWithIdentitySolutions()方法时,引用同一行的实例没有解析为一个实例,因为这是其预期的功能之一?
  • 为什么在使用这种方法时会有一个独立的跟踪器在后台运行,以至于使用这种方法的目标之一就是停止任何跟踪?

推荐答案

AsNoTrackingWithIdentityResolution不使用缓存(跟踪)实体,您的测试是错误的.

此模式仅在Query的作用域中有效.它重用由Include指令加载的实体来修复导航属性,并且不实例化具有相同类型和相同键的重复实体.这就是为什么它被称为WithIdentityResolution.

例如,如果您有以下类:

class Employee
{
    public int Id { get; set; }

    public ICollection<Order> Orders { get; set; }
}

class Orders
{
    public int Id { get; set; }
    public int EmployeeId { get; set; }

    public Employee Employee { get; set; }
}

和查询:

var result = context.Employees
   .Include(e => e.Orders)
        .ThenInclude(o => o.Employee) // can be omitted, just shows what we are trying to load
   .AsNoTrackingWithIdentityResolution();

这意味着每个加载的员工都将拥有带有初始化的Employee导航属性的订单,该属性具有使用身份识别解决方案的相同引用.

不带.ThenInclude(o => o.Employee)的同一查询也应该初始化Orders的Employee属性,因为Emploee被加载到Query中,身份解析可以在Query的作用域中找到他们以进行初始化.

仅使用AsNoTracking()将 for each Order新Employee对象实例化.

如果你正在加载大的对象图,这个方法很有用,它可以减少内存的使用和查询的复杂性.

Csharp相关问答推荐

如何使用FastEndpoints和.NET 8 WebAppliationBuilder进行集成测试?

为什么我不能更改尚未设置的模拟对象属性的值?

为什么这个Reflection. Emit代码会导致一个DDL ViolationException?

找不到网址:https://localhost:7002/Category/Add?区域= Admin.为什么我的URL是这样生成的?area = Admin而不是/Admin/

此反射有什么问题.是否发送值转换委托?

WeakReference未被垃圾收集

使用可信第三方的Iext8.Net pdf签名

共享暂存/生产环境中Azure事件中心的建议配置

在C#中,非静态接口方法的抽象和虚拟是冗余的吗?

EF核心区分大小写的主键

如何使用用于VS代码的.NET Maui扩展在我的iOS/Android设备或模拟器上进行调试?

C#按名称从类获取属性值类型<;t>;,我需要反射吗?

单元测试类型为HttpClient with Microsoft.Extensions.Http.Resilience

当try 测试具有协变返回类型的抽象属性时,类似功能引发System.ArgumentException

我的命名管道在第一次连接后工作正常,但后来我得到了System.ObjectDisposedException:无法访问关闭的管道

C#中类库项目的源代码生成器

Visual Studio,Docker容器-容器调用:连接被拒绝

将列表转换为带有逗号分隔字符串形式的值的字典

在.Net 8 Visual Studio 2022中启用本机AOT发布时发布失败

有没有更好的方法来使用LINQ获取整行的计算组