[英]Aggregating Left Join in NHibernate using QueryOver/ICriteria
[英]NHibernate / QueryOver: How to left join with parameter
NHibernate / QueryOver API中是否有一种方法可以传递映射中已经存在的参数(因此,它将此参数用作此特定实例上所有查询的固定值)。
我需要这个(或解决方法),因为我在数据库中有一个这样的视图:
CREATE VIEW ProblematicView
AS
SELECT
v.*,
-- lots of data
FROM someView v
LEFT JOIN someTable t ON v.ForeignKey = t.ForeignKey
现在,除了ForeignKey匹配之外,我还需要对以下属性进行额外检查:
AND t.SomeOtherValue = @myParameter
这是不可能的,因为无法将参数直接传递给视图。 使用表值函数,这是有可能的,但是我不知道如何将其映射到NHibernate / QueryOver。
而且,由于使用巨大的QueryOver语句来过滤所有剩余的属性(因为视图用于搜索业务实体),因此函数方法将难以实现。
目前,我正在将SomeOtherValue / @myParameter筛选器应用于整个视图,并将其作为QueryOver的一部分。
这是我的主要问题:
使用例如:
SELECT
v.*,
-- lots of data
FROM someView v
LEFT JOIN someTable t ON v.ForeignKey = t.ForeignKey AND t.SomeOtherValue = 123
(followed by alot of other property checks...)
将返回不同的结果(由于左连接,意图中包含t.SomeOtherValue的NULL条目)
比使用:
SELECT * FROM ProblematicView where SomeOtherValue = 123
(followed by alot of other property checks)
由于现在左联接发生在视图内部而无需检查SomeOtherValue,并且SomeOthervalue检查是独立于左联接应用的,因此将排除所有NULL值(这是错误的业务逻辑)。
还使用:
SELECT * FROM ProblematicView where SomeOtherValue = 123 OR SomeOtherValue = NULL
(followed by alot of other property checks)
似乎没有帮助,因为仍然会忽略NULL值...
因此,我可以想像的解决此问题的唯一方法是找到一种将我的SomeOtherValue属性以某种方式传递给视图的方法,以便它可以将其用作视图本身(而不是where子句中)的参数,或者也许以某种方式使用对模型使用基于sql表的函数以及参数...
编辑:
经过更多研究后,我设法简化了这个问题:
我正在尝试转换此SQL:
Select v.*, ... from (someView v LEFT JOIN someTable t ON v.ForeignKey = t.ForeignKey)
WHERE SomeOtherValue = 123
(其中SomeOtherValue来自someOtherTable)
对此:
Select v.*, ... from someView v LEFT JOIN someTable t on v.ForeignKey = t.ForeignKey
AND t.SomeOtherValue = 123
使用NHibernate / QueryOver。 请注意,在第二个版本中,直接在左联接中检查属性SomeOthervalue,而在第一个版本中,仅在左联接之后才错误地应用该属性。
我需要找到一种写后一个SQL语句的方法,可以将它放在视图中,同时仍然可以将123作为SomeOtherValue的参数传递。
您可以使用带有withClause
参数的JoinQueryOver
或JoinAlias
重载,将条件添加到join
子句中。 例如:
SomeTable stAlias = null;
session.QueryOver<ProblematicView>()
.Left.JoinAlias(
pv => pv.SomeTable, // Join path
() => stAlias, // alias assignment
st => st.SomeOtherValue == 123) // "with" clause
/* etc. */
QueryOver联接的“ with”部分将为SQL的left outer join
联接添加条件。 上面应该产生这个:
SELECT /* select list */
FROM [ProblematicView] this_
left outer join [SomeTable] sometable1_
on this_.Id = sometable1_.ProblematicViewId
and (sometable1.SomeOtherValue = 123 /* @p0 */)
如果我理解正确,那么应该可以解决您的问题。
关于添加“ with”子句的一些注意事项:
JoinQueryOver
和JoinAlias
重载都要求在执行连接时分配一个别名。 or
连接条件下生成SQL。 “ with”子句始终and
映射的联接条件一起使用(即FK→PK)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.