Кажется, AsNoTrackingWithIdentityResolution() не работает?

Я прочитал статью о методе 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

Эталонное сравнение давало результат только тогда, когда два сравниваемых экземпляра (которые были разрешены в один экземпляр) отслеживались средством отслеживания изменений контекста, в то время как другие экземпляры не были разрешены в один экземпляр. Я использую ядро ​​EF 8.0.2.

А сейчас:

  • Почему экземпляры, ссылающиеся на одну и ту же строку, не были разрешены в один экземпляр при использовании метода AsNoTrackingWithIdentityResolution() с их запросами, поскольку это одна из его ожидаемых функций?
  • Почему при использовании этого метода в фоновом режиме работает автономный трекер, и одной из целей использования этого метода было прекращение любого отслеживания?
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
208
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

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) также должен инициализировать свойство Employee Orders, поскольку сотрудники загружаются в запрос, а разрешение идентификации может найти их в области запроса для инициализации.

Использование всего лишь AsNoTracking() создаст экземпляр для каждого нового объекта «Сотрудник» Order.

IOW, этот метод полезен, если вы загружаете большой граф объектов, он может уменьшить использование памяти и сложность запросов.

Да, более простым примером будет получение заказов из context.Orders и включение сотрудников. При использовании AsNoTracking каждая сущность сотрудника будет отдельным объектом, даже если они указывают на одну и ту же строку в БД. AsNoTrackingWIthIdentityResolution будет гарантировать, что всем ссылкам на одного и того же сотрудника в заказах будет присвоена одна и та же ссылка на объект сотрудника. Ключевым моментом, как вы отметили, является то, что он применяется только в рамках этого одного запроса. Если ОП хочет иметь ссылки между запросами, ему следует использовать запрос отслеживания.

Steve Py 12.03.2024 00:25

Другие вопросы по теме