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

本文关键字:参数 连接 何使用 QueryOver NHibernate | 更新日期: 2023-09-27 18:30:16

NHibernate/QueryOver API中有没有办法传递映射中已有的参数(因此它使用该参数作为此特定实例上所有查询的固定值)。

我需要这个(或解决方法),因为我在数据库中有一个这样的视图:

CREATE VIEW ProblematicView
AS
SELECT
    v.*,
-- lots of data
FROM someView v
LEFT JOIN someTable t ON v.ForeignKey = t.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 的参数。

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

可以使用采用withClause参数的重载JoinQueryOverJoinAliasjoin子句添加条件。例如:

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"子句始终与映射的连接条件(即 FK → PK)and