2014-10-02 80 views
1

我有一個編輯器,人們可以在其中創建自定義的SQL查詢。這些查詢是NHibernate.IQuery對象。推遲執行在哪裏在sql

在我們的項目中,我們使用NHibernate.Linq.LinqExtensionMethods.Query來獲取一個IQueryable對象,該對象可用於應用被延遲執行的過濾器(數據庫上的所有內容)。

現在我想創建另一個基於自定義sql查詢的過濾器。 我想是這樣的:

queryable.Where(x=> <sql-query contains x>) 

我現在唯一可以做的就是提前執行SQL查詢,然後篩選與所得的元素列表的可查詢。

IList<T> elements = query.List<T>(); 
queryable.Where(x => elements.Contains(x)).ToList(); 

該方法的問題是,元素列表可能很大。如果可能的話,我想直接在數據庫上執行整個語句,以便我不必將所有對象傳送到我的應用程序,然後將所有對象作爲過濾器參數發送回數據庫...

編輯:第一個查詢(一個屈服元素的列表在第二個查詢檢查)從一個普通的SQL字符串構造如下:

ISQLQuery sqlQuery = CurrentSession.CreateSQLQuery(myQueryString);//create query 
sqlQuery.AddEntity(typeof (T)); //set result type 
IQuery query = sqlQuery.SetReadOnly(true); 

回答

0

如果您有編號的,那麼你應該在選擇它們您的query,並將其與第二個查詢中相應的id列進行比較。

var elementIdsToUseInContain = query 
    .Select(x => x.YourIdProperty); 
var result = queryable 
    .Where(x => elementIdsToUseInContain.Contains(x.YourIdPropertyToCompareTo)) 
    .ToList(); 

注:我沒有測試過它,但它是相當標準的Linq。這取決於如果NHibernate支持它,我不知道。

+0

感謝您的回覆,但我想我沒有讓我的觀點清楚。問題不在於元素列表上的過濾器......這相當簡單。但我的問題是,我不想預先執行元素列表。當列表變得很長時,我必須從db中獲取大量數據,然後在第二個查詢中再次將該數據發送到數據庫。我想要的是組合這兩個查詢,所以我只有一個查詢(以最小化開銷)。 – r3try 2014-10-02 07:53:59

+0

我知道。我的解決方案做到了。變量'elementIdsToUseInContain'是* query *,而不是查詢*的結果*。如果NHibernate足夠聰明,它將在構造SQL時結合這兩個查詢。實體框架en Linq-to-sql支持這一點。這將導致一個單一的SQL語句(至少在EF和L2S中,並且希望在NHibernate中也是如此)。 – Maarten 2014-10-02 08:50:03

+0

啊好的,沒有意識到,對於第一部分沒有toList()...不幸的是,NHibernate.IQuery接口沒有包含方法,因此我無法弄清楚如何將IQuery和IQueryable結合起來。問題是,我需要從普通的sql構建我的第一個查詢,因此我使用IQuery接口。 – r3try 2014-10-02 12:15:15