Какая разница .AsNoTracking()?

У меня есть вопрос относительно расширения .AsNoTracking(), поскольку все это совершенно новое и довольно запутанное.

Я использую контекст для каждого запроса для веб-сайта.

Многие мои объекты не меняются, поэтому их не нужно отслеживать, но у меня есть следующий сценарий, где я не уверен, что происходит с базой данных, или даже если это имеет значение в этом случае.

Этот пример - это то, что я сейчас делаю:

context.Set<User>().AsNoTracking()
// Step 1) Get user
context.Set<User>()
// Step 2) Update user

Это то же самое, что и выше, но удаление .AsNoTracking() с шага 1:

context.Set<User>();
// Step 1) Get user
context.Set<User>()
// Step 2) Update user

Шаги 1 и 2 используют один и тот же контекст, но встречаются в разное время. Я не могу понять, есть ли разница. Поскольку шаг 2 - это обновление, я предполагаю, что оба будут попадать в базу данных дважды в любом случае.

Может ли кто-нибудь сказать мне, в чем разница?

Ответ 1

Разница в том, что в первом случае получаемый пользователь не отслеживает контекст, поэтому, когда вы собираетесь сохранить пользователя обратно в базу данных, вы должны прикрепить его и правильно установить состояние пользователя, чтобы EF знал, что он должен обновить существующего пользователя, а не вставлять новый. Во втором случае вам не нужно это делать, если вы загружаете и сохраняете пользователя с одним и тем же экземпляром контекста, потому что механизм отслеживания обрабатывает это для вас.

Ответ 2

см. эту страницу Entity Framework и AsNoTracking

Что такое AsNoTracking Does

Entity Framework предоставляет ряд параметров настройки производительности, которые помогут вам оптимизировать производительность ваших приложений. Один из этих вариантов настройки - .AsNoTracking(). Эта оптимизация позволяет вам сообщить Entity Framework не отслеживать результаты запроса. Это означает, что Entity Framework не выполняет дополнительной обработки или хранения объектов, возвращаемых запросом. Однако это также означает, что вы не можете обновлять эти объекты, не привязывая их к диаграмме отслеживания.

есть значительный прирост производительности при использовании AsNoTracking

Ответ 3

Отключение отслеживания также приведет к потоковой передаче результирующих наборов в память. Это более эффективно, когда вы работаете с большими наборами данных и не нуждаетесь во всем наборе данных одновременно.

Литература:

Ответ 4

Отслеживание запросов LINQ to Entities

Использование NoTracking() рекомендуется, когда ваш запрос предназначен для операций чтения. В этих сценариях вы возвращаете свои сущности, но они не отслеживаются вашим контекстом. Это обеспечивает минимальное использование памяти и оптимальную производительность.

Pros

  • Улучшена производительность по сравнению с обычными запросами LINQ.
  • Полностью материализованные объекты.
  • Простейшая запись с синтаксисом, встроенным в программирование язык.

против

  • Не подходит для операций CUD.
  • Некоторые технические ограничения, такие как: Шаблоны с использованием DefaultIfEmpty для Запросы OUTER JOIN приводят к более сложным запросам, чем просто OUTER JOIN в Entity SQL.
  • Вы все еще не можете использовать LIKE с общим соответствием шаблону.

Дополнительная информация доступна здесь:

Рекомендации по производительности для Entity Framework

Entity Framework и NoTracking

Ответ 5

Если у вас есть что-то другое, изменяющее БД (скажем, другой процесс), и вам нужно убедиться, что вы видите эти изменения, используйте AsNoTracking(), иначе EF может дать вам последнюю копию, которую имел ваш контекст, следовательно, это нормально используйте новый контекст для каждого запроса:

http://codethug.com/2016/02/19/Entity-Framework-Cache-Busting/