У меня есть классы с круговой ссылкой "один к одному", и они выглядят примерно так.
public class Foo
{
public Bar Bar { get; set; }
/* Some irrelevant code */
}
а также
public class Bar
{
public Foo Foo { get; set; }
/* Some irrelevant code */
}
и свободная карта nhibernate
BarMap
{
Table("Bars");
// Some mappings
Reference(x => x.Foo).Column("FooId");
}
FooMap
{
Table("Foos");
// Some Mappings
HasOne(x => x.Bar).PropertyRef(x => x.Foo).Not.Lazy.Cascade.SaveUpdates();
}
Я понимаю, что вы не можете лениво загружать отношения "один к одному" в nhibernate, так что я хочу сделать, чтобы выбрать все из всех баров и присоединиться к Foo, когда я хочу что-то из Foo. Я решил, что мне нужно получить Bar, но когда я выполняю:
var foos = session.Query<Foo>().Where(/*Some boolean logic*/).Fetch(x => x.Bar).ToList();
Затем Nhibernates выполняет несколько операторов SQL, выбирая по одному столбцу для каждого Foo. Я хочу только выбрать дважды. Однажды для Foo и один раз для Bar - так как это не может быть ленивым. Как я могу это сделать?
Моя проблема заключалась в том, что у меня в баре была еще одна циркулярная ссылка на другой объект, скажем Баз:
BarMap
{
Table("Bars");
Reference(x => x.Foo).Column("FooId");
HasOne(x => x.Bar).PropertyRef(x => x.Bar).Not.Lazy.Cascade.SaveUpdates();
}
BazMap
{
Table("Baz");
Reference(x => x.Foo).Column("BarId");
}
Поэтому я решил проблему, присоединившись к Foo, Bar и Baz.
var Foos = session
.Query<Foo>()
.Fetch(x => x.Bar)
.ThenFetch(x => x.Baz)
.ToList();
Сортировка сверху, если учитывать, что мне действительно нужно несколько полей в таблице Foos.
Возможно, вы сможете использовать фьючерсы для достижения того, чего хотите. Например:
session.Query<Bar>().Fetch(x => x.Foo).ToFuture();
var foos = session.Query<Foo>().Where(/*Some boolean logic*/).Fetch(x => x.Bar).ToList();
Идея состоит в том, что использование ToFuture()
для первого запроса гарантирует, что оба запроса будут выполняться одновременно, и nhibernate может использовать результаты первого запроса, чтобы помочь заполнить второй запрос. Возможно, вам придется поиграть с реальными запросами, чтобы заставить вещи работать так, как вы ожидаете.