2011-07-01 88 views
0

我有一個關於在NHIBERNATE連接的問題。我們有一個問題,我們的sql查詢生成,但nhibernate。我們的db開發人員對原始sql進行了優化,使其能夠按照我們的需要進行工作,但我們需要更改nhibernate代碼以使生成的sql看起來像優化一樣。Nhibernate加入過濾

查詢的原始部件的部件是:

FROM PERSON_VISIT this_ 
        inner join PERSON_Basic per2_ 
         on this_.PERSON_ID = per2_.PERSON_ID 
        left outer join PERSONC_QUESTIONS perint10_ 
         on per2_.PERSON_ID = perint10_.PERSON_ID 
        left outer join TELEPHONE_QUESTIONS intaudit13_ 
         on perint10_.PP_QUESTIONS_ID = intaudit13_.PP_QUESTIONS_ID 
        inner join C_QUESTIONS intdef14_ 
         on perint10_.QUESTION_ID = intdef14_.QUESTION_ID 
          and perint10_.QUESTIONS_CODE = intdef14_.QUESTIONS_CODE 
          and perint10_.QUESTION_ID = intdef14_.QUESTION_ID 

優化之一是:

FROM PERSON_VISIT this_ 
        inner join PERSON_Basic per2_ 
         on this_.PERSON_ID = per2_.PERSON_ID 
        left outer join PERSONC_QUESTIONS perint10_ 
         on per2_.PERSON_ID = perint10_.PERSON_ID 
        left outer join TELEPHONE_QUESTIONS intaudit13_ 
         on perint10_.PP_QUESTIONS_ID = intaudit13_.PP_QUESTIONS_ID 
        left outer join C_QUESTIONS intdef14_ 
         on perint10_.QUESTION_ID = intdef14_.QUESTION_ID 
          and perint10_.QUESTIONS_CODE = intdef14_.QUESTIONS_CODE 
          and perint10_.QUESTION_ID = intdef14_.QUESTION_ID 
          and intdef14_.DISCIPLINE_CODE = this_.DISCIPLINE_CODE 

要變更查詢從內部連接到左外連接是容易的,我只改一行代碼:

 .CreateAlias("PersonInt.QuestionEntity", "IntDef", JoinType.LeftOuterJoin) 

但我怎麼可以添加

      and intdef14_.DISCIPLINE_CODE = this_.DISCIPLINE_CODE 

使用nhibernate代碼?

有一個選項可以將PERSON_VISIT定義中的引用添加到C_QUESTIONS,但問題在於PERSON_VISIT在任何地方都可以使用,我不希望此更改可能會打破其他查詢,我只想添加一行添加代碼,我該怎麼做?有什麼辦法可以訪問原始連接來改變它嗎?或者其他方式添加此

      and intdef14_.DISCIPLINE_CODE = this_.DISCIPLINE_CODE 

查詢? 我知道有人會說我們可以通過criteria.Add添加對查詢的限制,但它不是一個選項,因爲db開發人員優化了我們的查詢,從WHERE子句到連接都受到此限制。

如何在不更改模型定義的情況下快速完成該操作?只更改這一個查詢而不更改整個模型?

回答

0

感謝您的回答。我們在我們的項目中使用了NHibernate的2.0版本,所以我們沒有機會使用具有限制條件的.CreateAlias新方法。

我有固定的使用攔截器的問題:

public class SqlInterceptor : EmptyInterceptor, IInterceptor 
{ 
    SqlString IInterceptor.OnPrepareStatement(SqlString sql) 
    { 
     //manipulating with the sql 

     return sql; 
    } 
} 

 var factory = Session.SessionFactory; 
     var session = factory.OpenSession(new SqlInterceptor()); 

,用我的查詢,而無需改變。

2

可以使用HQL和Criteria API。

這個問題可以讓你答案:Adding conditionals to outer joins with nhibernate

像這樣的東西可能會解決您的問題。

.CreateAlias("PersonInt.QuestionEntity", "IntDef", JoinType.LeftOuterJoin, 
     Restrictions.EqProperty("DISCIPLINE_CODE", "IntDef.DISCIPLINE_CODE")) 
+0

這個答案很好。問題是我們使用的是nHibernate的2.0.0.4版本,我沒有可能使用這種方法,而且項目太大而無法測試所有代碼,因此我們需要快速解決此問題。也許你知道我如何在2.0.0.4中做到這一點?是否有可能操縱nHibernate生成的原始sql?導致其他唯一的解決方案是使用sql重寫方法。 – anderhil

+0

也許爲了讓執行計劃起作用,您可以移動該額外的連接子句並將其添加到WHERE子句中。希望SQL服務器足夠聰明,可以將其從內部計劃的加入位置推出,或者爲您提供正在尋找的優化計劃。 .Add(Restrictions.EqProperty(「DISCIPLINE_CODE」,「IntDef.DISCIPLINE_CODE」))' –

+0

正如我前面所說,這是我們的性能問題.Add(Restrictions.EqProperty(「DISCIPLINE_CODE」,「IntDef.DISCIPLINE_CODE」))in where子句。不知道爲什麼,但加入這個限制比在where子句中更快。快兩倍。我通過編寫攔截器並使用原始sql進行操作來解決此問題。謝謝。 – anderhil