Fluent NHibernate QueryOver to select items not in another table (left join)

偶尔善良 提交于 2019-12-13 16:10:46

问题


I have two tables:

all: id | propA | propB | someOtherColumn

hidden: id | propA | propB

and corresponding classes (Mapped, no relationship mapped yet)

I would like to get all rows from first table, minus any results which match by propA or propB property.

I managed to do it by Criteria API but would like to see how it is done with QueryOver API, if possible without subqueries but with a left excluding join.

Criteria version:

var dc1 = DetachedCriteria.For<hidden>()
    .Add(Restrictions.IsNotNull(Projections.Property("propA")))
    .SetProjection(Projections.Property("propA"));

var dc2 = DetachedCriteria.For<hidden>()
    .Add(Restrictions.IsNotNull(Projections.Property("propB")))
    .SetProjection(Projections.Property("propB"));



var query = db
    .CreateCriteria<all>()
    .Add(Restrictions.On<all>(c => c.someOtherColumn).IsLike("1"))
    .Add(Subqueries.PropertyNotIn("propA", dc1))
    .Add(Subqueries.PropertyNotIn("propB", dc2))

which gives roughly:

SELECT all.* 
FROM all
WHERE (all.someOtherColumn LIKE '1')
    and all.propA not in (SELECT hidden.propA FROM hidden WHERE hidden.propA IS NOT NULL) 
    and all.propB not in (SELECT hidden.propB FROM hidden WHERE hidden.propB IS NOT NULL)

It is ok, though it seems performance wise this would be better:

SELECT all.* 
FROM all
LEFT JOIN hidden ON all.propA = hidden.propA
LEFT JOIN hidden ON all.propB = hidden.propB
WHERE hidden.propA IS NULL
AND hidden.propB IS NULL 
AND (all.someOtherColumn LIKE '1')

If it is not possible to generate such a statement with unmapped relationships, I am open to suggestions on mapping.


回答1:


It seems to me that it's not possible to create joins without mapped relationships via QueryOver. See this answer.

With subqueries you can do something like this:

All allAlias = null;
var result = Session.QueryOver(() => allAlias)
               .WhereRestrictionOn(x => x.someOtherColumn).IsLike('1')
               .WithSubquery.WhereNotExists(QueryOver.Of<hidden>()
                     .Where(h => h.propA == allAlias.propB || h.propB == allAlias.propB)
                     .Select(h => h.Id))
               .List();


来源:https://stackoverflow.com/questions/44904844/fluent-nhibernate-queryover-to-select-items-not-in-another-table-left-join

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!