繁体   English   中英

NHibernate / QueryOver:如何使用参数离开联接

[英]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参数的JoinQueryOverJoinAlias重载,将条件添加到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”子句的一些注意事项:

  • 有趣的是,所有允许您指定“ with”子句的JoinQueryOverJoinAlias重载都要求在执行连接时分配一个别名。
  • 您(据我所知)不能在or连接条件下生成SQL。 “ with”子句始终and映射的联接条件一起使用(即FK→PK)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM