1

Я разрабатываю проект asp.Net mvc, используя первый подход сущностного кода. Но я стараюсь повысить производительность своего приложения. Я не понимаю, что Entity Framework снова запускает запрос базы данных или нет, если я снова получаю такое же условие. См. Мой сценарий ниже.Запустил ли Entity Framework запрос базы данных для уже запущенного запроса?

var item = context.Items.FirstOrDefault();// Database query will be run for this 
var start = item.Promotions.FirstOrDefault().Start; // Another query will be run for this 
var end = item.Promotions.FirstOrDefault().End; //Will another query be run again? Same query is run again for this 
var price = item.Promotions.FirstOrDefault().Price; //Here also 

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

ответ

3

Хотя ответ правильный есть другой вариант, чтобы рассмотреть

Вашего оригинального запрос

var item = context.Items.FirstOrDefault();// Database query will be run for this 
var start = item.Promotions.FirstOrDefault().Start; // Another query will be run for this 
var end = item.Promotions.FirstOrDefault().End; //Will another query be run again? Same query is run again for this 
var price = item.Promotions.FirstOrDefault().Price; //Here also 

Загрузка элемент, как объект прекращает чтение данных из объекта

var item = context.Items.FirstOrDefault();// Database query will be run for 

Теперь все объекты загружен хранятся в памяти для чтения без запроса

Теперь, чтобы получить данные, когда вы ленивы загрузка продвижение вар = item.Promotions.FirstOrDefault() И это даст еще один запрос

promotion.Start 
promotion.End 

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

var item = context.Items.Include(x=>x.Promotions).FirstOrDefault(); 

и тогда это будет только один запрос к БД, чтобы получить данные о пункте и е продвижение по службе.

Специальный выбор

Вы также можете обновить запрос, чтобы выбрать только те элементы, которые заинтересованы в с помощью:

var customObj = context.Promotions.Where(p=>p.ItemId==itemId).Select(x=>new{x.Start, x.End, x.Price}).FirstOrDefault(); 

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

Примечание использование SQL Profiler/муравьи профайлер и т.д., чтобы увидеть, что SQL вы создаете.

+0

Итак, я получаю как этот контекст.Items.Include (x => x.Promotions). Затем я получаю элемент, подобный этому элементу var item = items.FirstOrDefault(). Если U получит доступ к элементу item.Promotions.FirstOrDefault(), запрос будет запущен снова? –

+0

no он будет включать по умолчанию все экземпляры, связанные с элементом – cpoDesign

+0

Что делать, если отношения одного к одному? Пример var item = context.items.FirstOrDefault(); var start = item.Promotion.Start; var end = item.Promotion.End. Как вы можете видеть, я не привязывал их к переменной. Итак, другой запрос выполняется снова, когда я получаю дату окончания акции? –

1

Данные в базе данных могут быть изменены в то же время, поэтому EF снова выполняет запрос.

Для повышения производительности, просто кэшировать результат себя:

var item = context.Items.FirstOrDefault(); // Database query will be run for this 
var promotion = item.Promotions.FirstOrDefault(); // Another query will be run for this 
var start = promotion.Start; // No additional query 
var end = promotion.End;  // No additional query 
var price = promotion.Price; // No additional query 

BTW: Это не имеет ничего общего с отложенной загрузкой. «Ленивая загрузка» связана с ленивой загрузкой других объектов, на которые она ссылается. Он не связан с его данными.

+0

Большое спасибо. –

+0

Что делать, если отношения одного к одному? Пример var item = context.items.FirstOrDefault(); var start = item.Promotion.Start; var end = item.Promotion.End.Как вы можете видеть, я не привязывал их к переменной. Итак, другой запрос выполняется снова, когда я получаю дату окончания акции? –