Linq to NHibernate - выберите проблему с количеством - PullRequest
1 голос
/ 30 ноября 2010

Учитывая классы A и B, где

class A
{
 string Name;
 Ilist<B> BList;
}

class B
{
 string Name;
}

При отображении FluentNH отношение "многие ко многим", которое имеет значение HasManyToMany (x => xB) для A. B, не имеет ссылки на A. NHверсия 2.1.2.4000.

Каким должен быть запрос linq для выбора коллекции, в которой каждая строка содержит B.Name и количество A, содержащих этот B? Результатом должен быть список анонимных пользователей.Тип, у которого есть 2 поля: Имя и Количество.Результат также должен включать все B, следовательно, это должно быть внешнее соединение.

Мое намерение - получить результат с минимальным количеством обращений к базе данных, возможно, за один раз.

1 Ответ

3 голосов
/ 30 ноября 2010

Если вы хотите сделать это в Linq одним ударом в коде, вы можете сделать это ...

var result = Session.Linq<A>()
    .SelectMany(a => a.BList, (a, b) => new { b.Name, A = a.Id })
    .ToList()
    .GroupBy(x => x.Name)
    .Select(x => new { Name = x.Key, Count = x.Count() })
    .ToList();

NHibernate.Linq (2.1.2.4000) не может обработать GroupBy послеSelectMany кажется, поэтому первый ToList вытягивает все данные в память.Это неэффективно - подсчет SQL был бы лучше.

В качестве альтернативы, вы можете добавить загруженную коллекцию с отложенным доступом к вашему классу B, который восходит к A.Если вы используете таблицу «многие ко многим» в середине, это должно быть легко.

public class B
{
    public virtual string Name { get; set; }
    public virtual IList<A> AList { get; private set; }
}

Ваш запрос просто становится ...

var result = Session.Linq<B>()
    .Where(b => b.AList.Count > 0)
    .Select(b => new { b.Name, b.AList.Count }
    .ToList();

, что дает очень эффективныйSQL от Linq (с использованием счетчика) и дает тот же результат.

...