简体   繁体   English

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

[英]NHibernate / QueryOver: How to left join with parameter

Is there a way in NHibernate / QueryOver API to pass a parameter already in the mapping (so it uses the parameter as a fixed value for all queries on this particular instance). NHibernate / QueryOver API中是否有一种方法可以传递映射中已经存在的参数(因此,它将此参数用作此特定实例上所有查询的固定值)。

I need this (or a workaround) because I have a view like this in the Database: 我需要这个(或解决方法),因为我在数据库中有一个这样的视图:

CREATE VIEW ProblematicView
AS
SELECT
    v.*,
-- lots of data
FROM someView v
LEFT JOIN someTable t ON v.ForeignKey = t.ForeignKey

Now additionally to the ForeignKey match I need an additional check for a property like this: 现在,除了ForeignKey匹配之外,我还需要对以下属性进行额外检查:

AND t.SomeOtherValue = @myParameter

which is not possible as there is no way to pass parameters to a view directly. 这是不可能的,因为无法将参数直接传递给视图。 With a table valued function this would be possible but then I don´t know how to map it to NHibernate / QueryOver. 使用表值函数,这是有可能的,但是我不知道如何将其映射到NHibernate / QueryOver。

Also the function approach would be hard to realize as a huge QueryOver statement is used to filter all the remaining properties (as the view is used for searching business entities) 而且,由于使用巨大的QueryOver语句来过滤所有剩余的属性(因为视图用于搜索业务实体),因此函数方法将难以实现。

Currently I am applying the SomeOtherValue / @myParameter filter to the the entire view as a part of my QueryOver. 目前,我正在将SomeOtherValue / @myParameter筛选器应用于整个视图,并将其作为QueryOver的一部分。

This is my main problem: 这是我的主要问题:

Using for example: 使用例如:

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

will return a different result (NULL entries for t.SomeOtherValue included on intent due to left join) 将返回不同的结果(由于左连接,意图中包含t.SomeOtherValue的NULL条目)

than using: 比使用:

SELECT * FROM ProblematicView where SomeOtherValue = 123
 (followed by alot of other property checks)

As now the left join happens inside the view without checking for SomeOtherValue and as the SomeOthervalue check is applied independent on the left join, all the NULL values will be excluded (which is wrong business logic). 由于现在左联接发生在视图内部而无需检查SomeOtherValue,并且SomeOthervalue检查是独立于左联接应用的,因此将排除所有NULL值(这是错误的业务逻辑)。

Also using: 还使用:

SELECT * FROM ProblematicView where SomeOtherValue = 123 OR SomeOtherValue = NULL
 (followed by alot of other property checks)

does not seem to help, as NULL values are still ignored... 似乎没有帮助,因为仍然会忽略NULL值...

So the only way I can imagine to solve this problem would be to find a way to pass my SomeOtherValue property somehow to the view so that it can use it as a parameter in the view itself (instead of in the where clause) or maybe somehow use an sql table based function with parameter for the model... 因此,我可以想像的解决此问题的唯一方法是找到一种将我的SomeOtherValue属性以某种方式传递给视图的方法,以便它可以将其用作视图本身(而不是where子句中)的参数,或者也许以某种方式使用对模型使用基于sql表的函数以及参数...

EDIT: 编辑:

After some more research I managed to hopefully simplify the problem: 经过更多研究后,我设法简化了这个问题:

I am trying to convert this SQL: 我正在尝试转换此SQL:

Select v.*, ... from (someView v LEFT JOIN someTable t ON v.ForeignKey = t.ForeignKey) 
WHERE SomeOtherValue = 123

(where SomeOtherValue comes from someOtherTable) (其中SomeOtherValue来自someOtherTable)

to this: 对此:

Select v.*, ... from someView v LEFT JOIN someTable t on v.ForeignKey = t.ForeignKey
AND t.SomeOtherValue = 123

using NHibernate / QueryOver. 使用NHibernate / QueryOver。 Note that in the second version the property SomeOthervalue is checked against directly within the left join, where in the first version it is incorrectly applied only after the left join. 请注意,在第二个版本中,直接在左联接中检查属性SomeOthervalue,而在第一个版本中,仅在左联接之后才错误地应用该属性。

I need to find a way to write latter SQL statement in a way that I can put it inside a view while still being able to pass 123 as parameter for SomeOtherValue. 我需要找到一种写后一个SQL语句的方法,可以将它放在视图中,同时仍然可以将123作为SomeOtherValue的参数传递。

You can add a condition to a join clause using the overload of JoinQueryOver or JoinAlias that takes a withClause parameter. 您可以使用带有withClause参数的JoinQueryOverJoinAlias重载,将条件添加到join子句中。 For example: 例如:

SomeTable stAlias = null;

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

The "with" portion of the QueryOver join is what will add a condition to the left outer join in SQL. QueryOver联接的“ with”部分将为SQL的left outer join联接添加条件。 The above should generate this: 上面应该产生这个:

SELECT /* select list */
FROM   [ProblematicView] this_
       left outer join [SomeTable] sometable1_
         on this_.Id = sometable1_.ProblematicViewId
            and (sometable1.SomeOtherValue = 123 /* @p0 */)

If I understand correctly, this should help solve your problem. 如果我理解正确,那么应该可以解决您的问题。

A few things to note about adding a "with" clause: 关于添加“ with”子句的一些注意事项:

  • Interestingly, all of the overloads of JoinQueryOver and JoinAlias that allow you to specify a "with" clause require that you assign an alias when you do the join. 有趣的是,所有允许您指定“ with”子句的JoinQueryOverJoinAlias重载都要求在执行连接时分配一个别名。
  • You cannot (as far as I know) generate SQL with an or in the join condition. 您(据我所知)不能在or连接条件下生成SQL。 the "with" clause is always and ed with the mapped join condition (ie, FK → PK) “ with”子句始终and映射的联接条件一起使用(即FK→PK)

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

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