Использует ли LINQ to Entities экземпляры объектов повторно?

StackOverflow https://stackoverflow.com/questions/280270

  •  07-07-2019
  •  | 
  •  

Вопрос

Использование LINQ to Entities кажется отличным способом выполнять запросы к базе данных и получать реальные объекты CLR, которые я могу изменять, привязывать данные и т. д.Но если я выполню тот же запрос во второй раз, получу ли я обратно ссылки на те же объекты CLR или совершенно новый набор?

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

Это было полезно?

Решение

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

Различные DataContexts будут извлекать разные объекты, так что есть риск увидеть устаревшие данные, да.

Другие советы

В том же DataContext вы получите тот же объект, если он будет запрошен (DataContext поддерживает для этого внутренний кеш).

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

В зависимости от бизнес-ситуации может быть допустимо, чтобы вторая транзакция с устаревшими данными не выполнялась при фиксации.

Кроме того, представьте себе старый добрый сценарий IDataReader / DataSet. Два запроса вернут двух разных читателей, которые будут заполнять разные наборы данных. Таким образом, проблема дублирования данных не зависит от ORM.

[упс;обратите внимание, что этот ответ относится к Linq-to-SQL, а не к Entity Framework.]

Я оставил его здесь (а не удалил), потому что он частично соответствует теме и может быть полезен.


В дополнение к другим ответам обратите внимание, что контекст данных также имеет возможность избежать двустороннего обхода для простых запросов «по первичному ключу» - сначала он проверит кеш.

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

Итак, в основном, IIRC вам нужно использовать:

// uses object identity cache (IIRC)
var obj = ctx.Single(x=>x.Id == id);

Но нет:

// causes round-trip (IIRC)
var obj = ctx.Where(x=>x.Id == id).Single();
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top