AsNoTrackingWithIdentityResolution() 似乎不起作用?

问题描述 投票:0回答:1

我读了一篇关于 AsNoTrackingWithIdentityResolution() 方法的文章,它是一种无需跟踪即可进行身份解析的方法,并且在使用它时,与上下文不同的更改跟踪器在后台运行,以解析所引用的实体到一个实例的同一行。

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

// 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

仅当上下文更改跟踪器跟踪两个比较实例(解析为一个实例),而其他实例未解析为一个实例时,引用比较才会给出 true。我正在使用 EF core 8.0.2

所以现在:

  • 为什么在使用 AsNoTrackingWithIdentityResolution() 方法进行查询时,引用同一行的实例未解析为一个实例,因为这是其预期功能之一?
  • 为什么使用此方法时会在后台运行一个独立的跟踪器,以便使用此方法的目标之一是停止任何跟踪?
c# asp.net-core entity-framework-core
1个回答
0
投票

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

此模式仅在查询范围内有效。它重用由

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
属性,因为 Employeee 已加载到查询中,并且身份解析可以在查询的初始化范围中找到它们。

仅使用

AsNoTracking()
将为每个订单实例化新的 Employee 对象。

IOW,如果您正在加载大对象图,此方法很有用,它可能会减少内存使用量和查询复杂性。

© www.soinside.com 2019 - 2024. All rights reserved.