NHibernate QueryOver присоединиться к несвязанным лицам - PullRequest
9 голосов
/ 17 июня 2011

У меня работает следующий запрос, который дает желаемые результаты:

int associatedId = 123;

MyObject alias = null;

var subQuery = QueryOver.Of<DatabaseView>()
    .Where(view => view.AssociatedId == associatedId)
    .And(view => view.ObjectId == alias.ObjectId)
    .Select(view => view.ObjectId);

var results = session.QueryOver<MyObject>(() => alias)
    .WithSubquery.WhereExists(subQuery)
    .List();

DatabaseView был сопоставлен как фактическая сущность NHibernate (поэтому я могу использовать его с QueryOver), но он не связан сMyObject в сопоставлениях HBM.

Этот запрос возвращает IList с использованием SELECT ... FROM MyObject WHERE EXISTS (подзапрос для DatabaseView здесь).Как я могу переписать это, чтобы вернуть ту же информацию, но вместо этого используя JOIN?

Ответы [ 4 ]

7 голосов
/ 26 июля 2011

Вы можете присоединиться к несвязанным сущностям с помощью Linq в NHibernate 3 +

Как ни странно, вы используете элемент выражения запроса join:

from type1 in Repository.Query<MyType1>() 
join type2 in Repository.Query<MyType2>() 
on type1.Id equals type2.Id

Примечание: Repository.Query только что возвращаетсяIQueryable Query из сеанса

Я надеюсь, что есть решение для QueryOver, так как я не всегда хочу моделировать двусторонние отношения в моем домене, но они все еще полезны для запросов.

Кроме того, вы можете отобразить двусторонние отношения Access = "noop", используя Criteria API, не добавляя в ваши классы POCO:

http://ayende.com/blog/4054/nhibernate-query-only-properties

3 голосов
/ 19 апреля 2018

В NHibernate 5.1 это возможно для QueryOver через Entity Join :

int associatedId = 123;

MyObject alias = null;
DatabaseView viewAlias = null;

var results = session.QueryOver<MyObject>(() => alias)
    .JoinEntityAlias(() => viewAlias, () => viewAlias.ObjectId == alias.ObjectId && viewAlias.AssociatedId == associatedId)
    .List();
2 голосов
/ 31 августа 2016

Я понимаю, что этому вопросу 5 лет, и «правильный» ответ определенно состоит в том, что вы не можете сделать это с помощью QueryOver, как указывают другие ответы.Однако, если вам действительно нужна эта функциональность (как я это сделал), я нашел достойный обходной путь.

Решение состоит в том, чтобы использовать «запрос загрузчика» с собственным SQL-кодом в вашем отображаемом XML для создания связанной коллекции (см. http://nhibernate.info/doc/nhibernate-reference/querysql.html#querysql-load). В конкретном примере OP вы можете продолжить и отобразить свой DatabaseView как сущность, как предложено, и затем напишите в своем отображении следующее:

<class name="MyObject"...>
    ...
    <set name="MyViews" inverse="true">
        <key column="ObjectId" foreign-key="none"/>
        <one-to-many class="MyObject"/>
        <loader query-ref="myObjectViewsLoadQuery"/>
    </set>
</class>

Тогда нам просто нужно определить наше именованное myObjectViewsLoadQuery в необработанном SQL, чтобы объяснить NH, как объединить эти два элемента:

<sql-query name="myObjectViewsLoadQuery">
    <load-collection alias="view" role="MyObject.MyViews"/>
    SELECT view.*
    FROM DatabaseView view
    WHERE view.ObjectId = :id
</sql-query>

Теперь мы можем притворяться, будто в нашем запросе есть «настоящая» коллекция с именем MyViews, относящаяся MyObject к DatabaseView:

MyObject alias = null;
DatabaseView view = null;
var results = session.QueryOver<MyObject>(() => alias)
     .JoinAlias( () => alias.MyViews, () => view )
     //.Where( () => view.Property == "myValue" ) // optionally, restrict the view etc.
     .List();

Конечно, этоесли вы заботитесь только о «элегантном» запросе, вам придется столкнуться с большими трудностями. Однако если вы используете QueryOver по той причине, что вы хотите иметь возможность принимать произвольные входные выражения для фильтрации вашего DatabaseView или других подобных действий,это работает очень хорошо.

0 голосов
/ 17 июня 2011

Вы не можете сделать это, используя QueryOver, Criteria или Linq. Единственный способ сделать это - через HQL.

http://www.codewrecks.com/blog/index.php/2009/09/04/theta-join-in-hql-join-with-unrelated-entities/

...