NHibernate / QueryOver:如何使用参数保持连接

时间:2014-11-13 08:40:11

标签: c# sql nhibernate queryover

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

将返回不同的结果(由于左连接而包含在intent上的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的参数传递。

1 个答案:

答案 0 :(得分:2)

您可以使用带有join参数的JoinQueryOverJoinAlias重叠向withClause子句添加条件。例如:

SomeTable stAlias = null;

session.QueryOver<ProblematicView>()
    .Left.JoinAlias(
        pv => pv.SomeTable,              // Join path
        () => stAlias,                   // alias assignment
        st => st.SomeOtherValue == 123)  // "with" clause
    /* etc. */

&#34; with&#34; QueryOver连接的一部分是在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 */)

如果我理解正确,帮助您解决问题。

关于添加&#34;和#34;的一些注意事项子句:

  • 有趣的是,JoinQueryOverJoinAlias的所有重载都允许您使用&#34;来指定&#34;子句要求您在进行连接时指定别名。
  • 你不能(据我所知)在连接条件下用or生成SQL。 &#34;与&#34;子句始终and用映射连接条件(即FK→PK)