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

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


person dotnetnoob    schedule 31.08.2012    source источник


Ответы (6)


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

person Ladislav Mrnka    schedule 31.08.2012
comment
Можем ли мы получить те же преимущества для анонимных классов в запросе выбора, таком как context.Users.Select (u = ›new {Name = u.Name})? Спасибо. - person Dilhan Jayathilake; 07.02.2017
comment
@DilhanJayathilake: анонимные классы не представляют саму сущность, поэтому у них нет отслеживания. - person Ladislav Mrnka; 13.02.2017
comment
Поскольку EF6 иногда неправильно определяет ключ объекта в представлении, игнорирует ли AsNoTracking () ключ и, следовательно, является альтернативой ручному исправлению ключа (при условии, что другие преимущества ключа не нужны). - person crokusek; 08.11.2017
comment
Также обратите внимание, что наибольший эффект AsNoTracking заключается в том, что ленивая загрузка не работает. - person Douglas Gaskell; 23.05.2018

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

Что делает AsNoTracking

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

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

person Moji    schedule 02.04.2014
comment
Кажется, что иногда выигрыш может уравновешиваться: stackoverflow.com/questions/9259480/ - person Fabrice; 28.12.2016
comment
Мой прирост производительности со сложным запросом, загружающим родительские дочерние отношения с включением за один шаг, составил около 50%. - person Karl; 19.01.2018

Запросы LINQ to Entities не отслеживаются

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

Плюсы

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

Минусы

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

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

Вопросы производительности для Entity Framework

Entity Framework и NoTracking

person NullReference    schedule 13.06.2016

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

Использованная литература:

person Ronnie Overby    schedule 07.12.2013

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

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

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

person crokusek    schedule 06.02.2018
comment
Чтобы еще раз подчеркнуть важность этого для представлений, у меня есть запрос из представления, которое возвращает 7 уникальных записей при запуске через SSMS. При запуске через EF без модификатора AsNoTracking я получаю первую запись, три копии второй и три копии третьей. Чтобы исправить это, потребовалось много недоверчивых головокружений, и это было исправлено с помощью AsNoTracking! - person Ade; 22.03.2018
comment
У меня была такая же проблема при использовании Linq to Entities при запросе представления без первичных ключей. Об AsNoTracking узнал только через полдня ломания головы. Это сообщение на форуме ASP.Net в конечном итоге привело меня к этому. forum.asp.net/t/ - person red_dorian; 14.09.2018

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

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

person andrew pate    schedule 04.07.2017