Все зависит от того, как определены ваши сущности и включена ли отложенная загрузка.Ваш запрос к 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).