问题
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