簡體   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