Все зависит от того, как определены ваши объекты и включена ли ленивая загрузка. Ваш запрос к 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 должна гарантировать, что свойства навигации правильно заполнены связанными сущностями, но это работает только тогда, когда ленивая загрузка отключена, но сущности отслеживаются по контексту (ну, я никогда не пробовал это с DbContext API, но он работал с ObjectContext API) .
person
Ladislav Mrnka
schedule
08.05.2011