Яку різницю має .AsNoTracking ()?


228

У мене є питання щодо .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 - це оновлення, я здогадуюсь, що обидва в будь-якому випадку потраплять у базу даних двічі.

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

Відповіді:


187

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


1
Чи можемо ми отримати однакові переваги для анонімних класів у вибраному запиті, наприклад у контексті.Users.Select (u => new {Name = u.Name})? Дякую.
Ділхан Джаятілаке

6
@DilhanJayathilake: Анонімні класи не представляють собою сутність, тому вони не мають відстеження.
Ладислав Мрнка

1
Оскільки EF6 іноді неправильно встановлює ключ сутності у представленні даних, чи AsNoTracking () ігнорує ключ і, таким чином, є альтернативою фіксації ключа вручну (припускаючи, що інші переваги ключа не потрібні).
crokusek

4
Також зауважте, найбільший ефект, який має AsNoTracking, полягає в тому, що ледача завантаження не буде працювати
Дуглас Гаскелл

170

див. цю сторінку Entity Framework та AsNoTracking

Що робить AsNoTracking

Entity Framework пропонує ряд варіантів настройки продуктивності, щоб допомогти вам оптимізувати продуктивність ваших додатків. Один з таких варіантів настройки є .AsNoTracking(). Ця оптимізація дозволяє сказати Entity Frameworkне відслідковувати результати запиту. Це означає, що Entity Frameworkне виконується додаткова обробка та зберігання об'єктів, які повертаються запитом. Однак це також означає, що ви не можете оновити ці об'єкти без повторного приєднання їх до графіка відстеження.

за допомогою AsNoTracking можна досягти значних прибутків


11
Здається, іноді вигоди можуть врівноважуватися: stackoverflow.com/questions/9259480/…
Fabrice

3
Мій приріст ефективності за допомогою складного запиту, що завантажує стосунки батьків-дитини з включенням в один крок, становив близько 50%
Карл

53

Немає відстеження LINQ до запитів сутностей

Використання AsNoTracking () рекомендується, коли ваш запит призначений для операцій з читанням. У цих сценаріях ви повертаєте свої особи, але вони не відстежуються вашим контекстом. Це забезпечує мінімальне використання пам'яті та оптимальну продуктивність

Плюси

  1. Підвищена продуктивність щодо регулярних запитів LINQ.
  2. Повністю матеріалізовані об’єкти.
  3. Найпростіше писати за допомогою синтаксису, вбудованого в мову програмування.

Мінуси

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

Більше інформації тут:

Міркування щодо ефективності Entity Framework

Entity Framework та NoTracking


34

Відключення відстеження також призведе до потокового набору результатів у пам'ять. Це більш ефективно, коли ви працюєте з великими наборами даних і не потрібно весь набір даних відразу.

Список літератури:


10

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

Це надзвичайно корисно при читанні представлення даних, яке не підтримує унікальний ключ, тому що, можливо, деякі поля є нульовими, або характер подання не піддається логічному індексуванню.

У цих випадках "ключ" може бути встановлений у будь-якому стовпчику, що не зводиться нанівець, але тоді AsNoTracking () повинен бути використаний для кожного запиту, що запитує ще (дублюється за ключем), буде пропущено.


2
Тільки щоб ще раз підтвердити важливість цього питання у Views, у мене є запит із представлення даних, яке повертає 7 унікальних записів під час роботи через SSMS. Під час запуску через EF, без модифікатора AsNoTracking, я отримую перший запис, три копії другого і три копії третього. Це виправдало багато недовірливих подряпин по голові, і це використовувало AsNoTracking!
Аде

У мене була така сама проблема, коли я використовував Linq для Entities, коли запитував перегляд без первинних ключів. Про AsNoTracking дізналися лише через пів дня вичісування голови. Цей форум на форумі ASP.Net врешті-решт привів мене до цього. forums.asp.net/t/…
red_dorian

6

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

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.