Fluent NHibernate QueryOver以选择不在另一个表中的项目(左连接)



我有两个表:

all:id | propA | propB | someOtherColumn

hidden:id | propA | propB

和相应的类(已映射,尚未映射关系)

我想从第一个表中获取所有行,减去与 propApropB属性匹配的任何结果。

我设法通过标准 API 做到这一点,但想看看如何使用 QueryOver API 完成它,如果可能的话,没有子查询,但有一个左排除连接。

标准版本:

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))

粗略给出:

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)

没关系,尽管看起来性能明智,这会更好:

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')

如果无法生成具有未映射关系的此类语句,我愿意接受有关映射的建议。

在我看来,如果没有通过 QueryOver 映射的关系,就不可能创建连接。 看到这个答案。

使用子查询,您可以执行以下操作:

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();

最新更新