2013-04-09 175 views
2

對子查詢「IN」參數是否可以使用自定義SQL?目前,我們成功地構建了子查詢(subQueryEstate),但它是一個複雜的SQL塊,可能需要一段時間才能處理大型數據集。該代碼使用我們現有的子查詢生成的查詢如下:NHibernate和自定義SQL子查詢(使用臨時表)

session.QueryOver(() => cAlias) 
.WithSubquery.WhereProperty(x => x.CPE.ID).In(subQueryEstate) 
.JoinAlias(x => x.Costs,() => aCosts, JoinType.LeftOuterJoin) 
.JoinAlias(x => x.Open,() => aOpen, JoinType.InnerJoin) 
.List(); 

爲了提高執行的速度,我們有一個想法,使用臨時表(事務生命週期),我們將與ID的填充。然後想法是加入臨時表或使用更簡單的子查詢(SELECT ID FROM TEMP_TABLE)而不是更復雜的原始表。

我們可以使用一個未映射爲NHibernate子查詢的表嗎?我們可以編寫自定義SQL或創建一個分離條件作爲參數傳遞給IN子句嗎?我們希望保留NHibernate爲查詢的其餘部分生成正確的SQL的事實。

理想情況下是這樣的:

session.QueryOver(() => cAlias) 
.WithSubquery.WhereProperty(x => x.CPE.ID).In("SELECT ID FROM TEMP_TABLE") 
.JoinAlias(x => x.Costs,() => aCosts, JoinType.LeftOuterJoin) 
.JoinAlias(x => x.Open,() => aOpen, JoinType.InnerJoin) 
.List(); 

的思考?想法?可能有一個我們沒有想過的更優雅的解決方案。

+0

我想使用一個存儲過程,它返回無論是IDS,甚至完全成熟的記錄可能是最好的選擇這裏。 – Rippo 2013-04-09 05:51:25

回答

1

最後我們用臨時表來解決問題。由於我們的應用程序使用了Firebird數據庫,因此我們創建了四個具有「事務」生命週期的全局臨時表。也就是說,臨時表中的數據只對交易的有效期有效。

用來創建臨時表的SQL(注意,我們創建了四個,以滿足我們的使用情況)

上提交刪除行創建全局臨時表TEMP_TABLE_ID1(ID BIGINT NOT NULL); CREATE INDEX IDX_TEMP_TABLE_ID1 ON TEMP_TABLE_ID1(ID);

使用臨時表,我們現在可以使用主查詢中的ID來系統地填充它們。通過使用子查詢或連接到臨時表來過濾後續查詢,這比對每個「下游」查詢使用大型子查詢要快得多。使用臨時表可顯着提高性能,並且因爲這些表只對交易的有效期有效,這意味着我們不必擔心交叉交易污染和/或清除數據表。

一個非常整潔的解決方案。

全局臨時表(火鳥) http://www.firebirdsql.org/refdocs/langrefupd21-ddl-table.html

+1

我仍然好奇你是如何讓NHibernate映射臨時表的。既然你使用「在提交刪除行」我假設你在同一個事務中創建它們,你打算使用它們? 那麼你同時在NHibernate中執行一個即時映射嗎? – Joppe 2014-11-19 14:10:30

+0

@ paligap你能解釋一下你如何用nhibernate吸引了這個?我有同樣的問題? – Rafi 2016-11-02 10:14:10