One-To-One Nhibernate вызывает несколько операторов SQL

1

У меня есть классы с круговой ссылкой "один к одному", и они выглядят примерно так.

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 - так как это не может быть ленивым. Как я могу это сделать?

Теги:
one-to-one
nhibernate
fluent-nhibernate

2 ответа

0
Лучший ответ

Моя проблема заключалась в том, что у меня в баре была еще одна циркулярная ссылка на другой объект, скажем Баз:

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.

0

Возможно, вы сможете использовать фьючерсы для достижения того, чего хотите. Например:

session.Query<Bar>().Fetch(x => x.Foo).ToFuture();
var foos = session.Query<Foo>().Where(/*Some boolean logic*/).Fetch(x => x.Bar).ToList();

Идея состоит в том, что использование ToFuture() для первого запроса гарантирует, что оба запроса будут выполняться одновременно, и nhibernate может использовать результаты первого запроса, чтобы помочь заполнить второй запрос. Возможно, вам придется поиграть с реальными запросами, чтобы заставить вещи работать так, как вы ожидаете.

  • 0
    Я обнаружил еще одну проблему в своем коде, у Bar есть круговая взаимно-однозначная ссылка на другой класс точно так же, как у Foo ...

Ещё вопросы

Сообщество Overcoder
Наверх
Меню