То, что вы описываете, не является проблемой N + 1.Пример проблемы N + 1: здесь .N + 1 означает, что вы выполняете N + 1 выбор вместо одного (или двух).В вашем примере это, скорее всего, будет означать:
// Lazy loads all N Orders in single select
foreach(var order in MyAccount.Orders)
{
// Lazy loads all Items for single order => executed N times
foreach(var orderItem in order.Items)
{
...
}
}
Это легко решить с помощью:
// Eager load all Orders and their items in single query
foreach(var order in context.Accounts.Include("Orders.Items").Where(...))
{
...
}
Ваш пример выглядит для меня действительным.У вас есть коллекция, которая выставляет IEnumerable
, и вы выполняете операцию Count
над ней.Коллекция загружается лениво и подсчет выполняется в памяти.Возможность перевода запроса Linq в SQL доступна только в IQueryable
с деревьями выражений, представляющими запрос.Но IQueryable
представляет запрос = каждый доступ означает новое выполнение в БД, поэтому, например, проверка цикла в цикле будет выполнять запрос БД в каждой итерации.
Так что это больше о реализации динамического прокси.
Подсчет связанных сущностей без их загрузки будет уже возможен в первом коде CTP5 (окончательный выпуск будет называться EF 4.1) при использовании DbContext
вместо ObjectContext
, но не путем прямого взаимодействия со сбором.Вам нужно будет использовать что-то вроде:
int count = context.Entry(myAccount).Collection(a => a.Orders).Query().Count();
Query
метод возвращает подготовленный IQueryable
, который, вероятно, и запускает EF, если вы используете отложенную загрузку, но можете дополнительно изменить запрос - здесь я использовал Count
.