Запрос дочерних коллекций сущности в Entity Framework 4.1 - PullRequest
2 голосов
/ 08 мая 2011

У меня есть набор сущностей, которые я запросил у IDbSet в моем DbContext.Теперь я хочу перебрать каждую сущность и запросить их дочерние коллекции, которые определены в сущности как ICollection.Правильно ли вызывать AsQueryable () для дочерних коллекций и выполнять мой запрос linq для этого?Если так, мои запросы будут linq-to-objects или объект коллекции, заполненный EF, реализует IQueryable, который отправляется в базу данных?

Спасибо за любую информацию по этому вопросу.

1 Ответ

5 голосов
/ 08 мая 2011

Все зависит от того, как определены ваши сущности и включена ли отложенная загрузка.Ваш запрос к IDbSet будет linq-to-entity.Если отложенная загрузка включена, доступ к каждому свойству навигации загруженного объекта вызовет запрос к базе данных, который загрузит все связанные объекты.AsQueryable не имеет никакого эффекта, здесь вы все равно будете выполнять запрос linq-to-objects для всех загруженных данных.В таком сценарии действительно лучше использовать готовую загрузку и загружать связанные объекты вместе с основным объектом:

var query = context.YourEntitySet.Include(e => e.YourNavProperty);

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

Если у вас много связанных сущностей и вы действительно хотите загрузить только очень маленькое подмножество, вы можете использовать следующий подход:

context.Entry(yourLoadedMainEntity)
       .Collection(e => e.YourNavProperty)
       .Query()
       .Where(...)
       .Load();

Это способ заставить EF загрузитьтолько подмножество связанных объектов с linq-to-entity.Вы все еще должны выполнить это для каждого загруженного основного объекта.Выполнение такого количества запросов выполняется очень медленно.Это все еще N + 1 проблема .

Другая и наиболее сложная оптимизация - загрузка всех основных объектов в одном запросе и всех связанных объектов в другом запросе:

var query = context.YourEntitySet;
var relatedQuery = from e in context.YourRelatedEntitySet
                   join m in context.YourEntitySet on e.MainId equals m.Id
                   where ...
                   select e;

Как только вы выполните оба запроса, Entity Framework должен убедиться, что свойства навигации правильно заполнены связанными сущностями, но это работает только тогда, когда отложенная загрузка отключена, но сущности отслеживаются по контексту (хорошо, я никогда не пробовал это с API DbContext, но он работал с API ObjectContext).

...