NHibernate: возвращает ссылочное свойство без отложенной загрузки, используя SetProjection - PullRequest
2 голосов
/ 21 января 2011

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

public class Foo
{
    public virtual Guid Id { get; set; }
    public virtual Bar Bar { get; set; }
}
public class Bar
{
    public virtual Guid Id { get; set; }
    public virtual string Name { get; set; }
}

У меня есть следующие критерии:

return Session.CreateCriteria<Foo>("f")
    .CreateAlias("f.Bar", "b")
    .SetProjection(Projections.Property("f.Bar"))
    .List<Bar>();

Это создает следующий SQL:

select b.Id from Foo f
inner join Bar on f.BarId = b.Id

Обратите внимание, как возвращается только Id of Bar, а не весь класс.Как мне получить все столбцы бара вместо этого?

Ответы [ 3 ]

2 голосов
/ 24 февраля 2011

Решение зависит от ваших потребностей.

Прежде всего если вам нужно вернуть сущность Bar, тогда ваши начальные критерии должны иметь тип Bar , поэтому вы просто:

session.CreateCriteria<Bar>().
       .List<Bar();

Если вам нужно добавить некоторые ограничения на основе Foo, то есть два способа.

  1. Использовать HQL

    session.CreateQuery(

        "select b " +
        "from Foo f " +
        "inner join f.Bar b " +
        "where f.Id = 9 ")
    .List();
    
  2. Использовать только свойство запроса. Сделайте это, добавив access = "noop" в ваш файл отображения Bar.

    <many-to-one name="foo" access="noop" class="Foo" column="FooFk"/>

Обратите внимание, что модель вашего домена не должна меняться! Вам не нужно добавлять это свойство / поле "foo" в класс Bar. Теперь вы можете использовать это свойство в своих запросах, например:

session.CreateCriteria<Bar>()
    .CreateAlias("foo", "f")
    .Add(Restrictions.Eq("f.Id", 9))
    .List<Bar>();
0 голосов
/ 27 февраля 2011

Если приведенный выше запрос критериев не сработает, это простой HQL-запрос, который должен помочь.

var hqlQuery="select b from Foo as f inner join f.Bar as b";

Теперь выполните этот запрос следующим образом:

Session.CreateQuery(hqlQuery).List<Boo>();

теперь вы можете добавить условие where к вашему запросу, если хотите.

Надеюсь, это поможет ... Я могу рассказать вам, как это сделать с помощью Criteria, но я думаю, что вам будет немного легче его использовать, так как вам, кажется, удобно с SQL.

0 голосов
/ 25 февраля 2011

Если это не соответствует ни одному из критериев, используйте DetachedCriteria:

var subquery = DetachedCriteria.For<Foo>("f")
    .SetProjection(Projections.Property("f.Bar"))
    // more filter criteria ...

return session.CreateCriteria<Bar>
    .SetProjection(Subqueries.PropertyIn("id", subquery));

, который создает sql следующим образом:

select Bar.*
from Bar
where Bar.id in (Select b.id from Foo f inner join Bar b on ...)

Очевидно, имеет смысл только если выВ подзапросе есть несколько критериев фильтрации, основанных на Foo.

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