NHibernate 3. Альтернативы ThenFetch в QueryOver

Я использую NHibernate 3.0 как с провайдером LINQ, так и с QueryOver. Иногда мне нужно быстро загрузить связанные данные, и на помощь приходит метод «Fetch», как в LINQ, так и в QueryOver. Теперь у меня есть специальный сценарий, в котором я хочу загрузить свойство не напрямую на втором уровне, например:

Foo f = ...;
f.A.B.C

с LINQ нет проблем, так как вы можете "связывать" выборки с помощью метода "ThenFetch", например:

var result = Session.Query<Foo>().Fetch(a => a.A).ThenFetch(b => b.B).ThenFetch(c => c.C).ToList();

В QueryOver такого метода нет, так как же добиться того же результата?

Заранее спасибо.


person psousa    schedule 26.01.2011    source источник


Ответы (3)


На самом деле мне удалось решить эту проблему, используя два разных подхода:

Подход один:

Session.QueryOver<Foo>().Fetch(x => x.A).Fetch(x => x.A.B).Fetch(x => x.A.B.C)

Подход второй:

A a = null;
B b = null;
C c = null;

Session.QueryOver<Foo>()
    .JoinAlias(x => x.A, () => a)
    .JoinAlias(() => a.B, () => b)
    .JoinAlias(() => b.C, () => c)

Оба работают (хотя я не совсем уверен, что один из них сгенерировал «внутреннее», а другой «внешнее» соединение).

person psousa    schedule 26.01.2011
comment
Подход два, кажется, работает только для One to One, он не работает с коллекциями. - person Phill; 12.04.2011
comment
Я беру это назад, это работает, если вы укажете тип соединения для коллекции, по умолчанию он пытается выполнить внутреннее соединение. Если вы укажете левое внешнее соединение, оно работает отлично. - person Phill; 12.04.2011
comment
Разве FetchType (Eager, Lazy, Default) не нужен после Fetch()? - person Andreas H.; 13.03.2012
comment
Неа. По крайней мере, этого не было, когда я опубликовал этот ответ (с NH 3.0) - person psousa; 13.03.2012
comment
Хотя этот ответ правильный, в моем собственном случае я специально искал дочерний элемент коллекции или списка. В этом случае @xanatos указывает, что вам просто нужно получить доступ к первому элементу коллекции/списка, чтобы осчастливить компилятор C#: query .Fetch(x => x.SomeEnumerable) .Fetch(x => x.SomeEnumerable.First().SomeProperty) Когда NHibernate действительно проверяет это лямбда-выражение, он игнорирует вызов .First() и просто смотрит на цепочка собственности. Осознание этого имело для меня огромное значение. - person adamjcooper; 09.10.2012


Я думаю, вы можете сделать это с помощью JoinQueryOver.

IQueryOver<Relation> actual =
   CreateTestQueryOver<Relation>()
    .Inner.JoinQueryOver(r => r.Related1)
    .Left.JoinQueryOver(r => r.Related2)
    .Right.JoinQueryOver(r => r.Related3)
    .Full.JoinQueryOver(r => r.Related4)
    .JoinQueryOver(r => r.Collection1, () => collection1Alias)
    .Left.JoinQueryOver(r => r.Collection2, () => collection2Alias)
    .Right.JoinQueryOver(r => r.Collection3)
    .Full.JoinQueryOver(r => r.People, () => personAlias); 
person Bas    schedule 26.01.2011