Какая разница.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() рекомендуется, когда ваш запрос предназначен для операций чтения. В этих сценариях вы возвращаете свои сущности, но они не отслеживаются вашим контекстом.Это обеспечивает минимальное использование памяти и оптимальную производительность
плюсы
- улучшена производительность по сравнению с обычными запросами LINQ.
- полностью материализованные объекты.
- проще всего писать с синтаксисом, встроенным в Программирование язык.
минусы
- не подходит для операций с жвачкой.
- некоторые технические ограничения, такие как: шаблоны с использованием DefaultIfEmpty для Внешние запросы соединения приводят к более сложным запросам, чем простые внешние Операторы JOIN в Entity SQL.
- вы все еще не можете использовать как с общим шаблоном.
более подробная информация доступна здесь:
отключение отслеживания также приведет к потоковой передаче ваших результирующих наборов в память. Это более эффективно, когда вы работаете с большими наборами данных и не нужен весь набор данных сразу.
ссылки:
AsNoTracking () позволяет обойти требование "уникальный ключ на запись" в EF (явно не упоминается другими ответами).
Это чрезвычайно полезно при чтении представления, которое не поддерживает уникальный ключ, потому что, возможно, некоторые поля являются nullable или природа представления не является логически индексируемым.
для этих случаев "ключ" может быть установлен в любой столбец, не допускающий null, но затем AsNoTracking() должен использоваться с каждым запросом else records (дублировать по ключу) будут пропущены.
Если у вас есть что-то еще изменить в БД (скажем, другой процесс) и нужно убедиться, что вы видите эти изменения, используйте
AsNoTracking(), в противном случае EF может дать вам последнюю копию, которую имел ваш контекст, поэтому хорошо обычно использовать новый контекст каждый запрос:http://codethug.com/2016/02/19/Entity-Framework-Cache-Busting/
Comments