Какая разница.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-это обновление, я предполагаю, что в любом случае оба попадут в базу данных дважды.

кто может сказать мне, в чем разница?

6 ответов


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


видите эту страницу Entity Framework и AsNoTracking

Что Делает AsNoTracking

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

значительные увеличения представления, котор нужно иметь путем использование AsNoTracking


нет отслеживания запросов LINQ к сущностям

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

плюсы

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

минусы

  1. не подходит для операций с жвачкой.
  2. некоторые технические ограничения, такие как: шаблоны с использованием DefaultIfEmpty для Внешние запросы соединения приводят к более сложным запросам, чем простые внешние Присоединяйтесь к отчетности в сущности в SQL.
  3. вы все еще не можете использовать как с общим шаблоном.

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

соображения производительности для Entity Framework

Entity Framework и NoTracking


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

ссылки:


AsNoTracking () позволяет обойти требование "уникальный ключ на запись" в EF (не упоминается явно другими ответами).

Это чрезвычайно полезно при чтении представления, которое не поддерживает уникальный ключ, потому что, возможно, некоторые поля являются nullable или природа представления не является логически индексируемым.

для этих случаев "ключ" может быть установлен в любой столбец, не имеющий значения null, но затем AsNoTracking() должен использоваться с каждой записью запроса else (дубликат по ключу) будут пропущены.


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

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