Фильтр детей без объединений в nHibernate - PullRequest
1 голос
/ 15 июля 2009

У меня проблема при попытке выполнить следующее с nHibernate:

  • Стремительная загрузка.
  • Используйте selects (вот моя проблема, я могу сделать это только с помощью объединений)
  • Фильтрация детей.

Давайте рассмотрим пример, где у нас есть класс RichPerson, который может иметь несколько классов: автомобили, дома, мотоциклы и компании. Все сопоставлены с различными сущностями с разными таблицами.

Если я попробую следующее:

session.CreateCriteria(typeof (RichPerson))
    .Add(Expression.Eq("Id", someId))
    .CreateCriteria("Cars")
    .Add(Expression.Eq("Brand","Ferrari")

nHibernate создаст внутреннее соединение, чтобы получить автомобили. Если RichPerson некоторых автомобилей Ferrari, объединение отправит дублированные данные.

Даже с .SetFetchMode("Cars",FetchMode.Select) nHibernate делает соединение.

Полагаю, объединение происходит потому, что я спрашиваю: богатого человека с идентификатором X и с автомобилями Ferrari Таким образом, соединение необходимо. Но я просто хочу предварительно загрузить (как-то) автомобили Ferrari. И используйте их как guy.Cars.

Уф! Я не знаю, правильно ли я выразил себя. В любом случае, спасибо, что уделили мне время.

Ответы [ 3 ]

0 голосов
/ 16 июля 2009

Вы говорите, что отображение для RichPerson имеет свойство Cars с FK Brand, верно? Если это так, это <many-to-one>, чем у вас все в порядке, вы можете сделать это и просто пропустить использование CreateCriteria, и все будет в порядке, поскольку поле Brand находится в таблице RichPerson.

Но если это <one-to-many>, как мне кажется, тогда да, вам нужно выполнить объединение, поскольку поле Brand хранится не в таблице RichPerson, а в Cars таблица, на которую ссылается поле RichPerson.Id, которое находится в поле Cars.RichPersonId (или как вы его называете).

Если это не имеет смысла, опубликуйте файлы сопоставления, и мы сможем подтвердить правильный путь для вас.

0 голосов
/ 09 декабря 2009

Я просто хочу предварительно загрузить (кое-как) Автомобили Ferrari. И использовать их как guy.Cars.

Похоже, у вас проблема с ленивой инициализацией.

Вот интересный пост об этом:

http://nhforge.org/wikis/howtonh/lazy-loading-eager-loading.aspx

Короче, похоже, ваш запрос в порядке. Но сразу после вашего запроса (пока сеанс еще открыт) попробуйте добавить:

NHibernateUtil.Initialize(guy.Cars);

Это заставит инициализировать вашу сущность Автомобили, так что вы сможете немедленно использовать ее.

0 голосов
/ 15 июля 2009

Вы должны сделать соединение, чтобы проверить критерии в связанной таблице. Там нет никакого способа обойти это. Вы также должны предварительно загрузить данные в связанную таблицу, немедленно создав их экземпляры.

session.CreateCriteria(typeof (RichPerson))
    .Add(Expression.Eq("Id", someId))
    .SetFetchMode("Cars", FetchMode.Join)
    .CreateCriteria("Cars")
    .Add(Expression.Eq("Brand","Ferrari");

Это также можно сделать с помощью HQL, например:

"SELECT p FROM RichPerson p inner join fetch p.cars c where p.id=:id and c.brand=:brand"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...