2010-10-12 84 views
1

考慮以下LINQ到NHibernate的查詢:LINQ查詢不無.ToList工作()

var q1 = from se in query.ToList<SomeEntity>() 
    where 
    prop1 == "abc" 
    select se; 

var q2 = from se in q1 
    where 
    m1(se.prop2) == "def" 
    select se; 

q2不會與錯誤作:「方法M1,未實現」。但與下面的查詢代替q2,一切正常的話:

var q2 = from se in q1.ToList<SomeEntity>() 
    where 
    m1(se.prop2) == "def" 
    select se; 

爲什麼出現這種情況?我怎樣才能得到第一個查詢工作呢?這是LINQ-to-NHibernate發生的事情,還是發生在所有LINQ查詢中?

回答

3

因爲LINQ提供者無法將方法m1轉換爲兼容的SQL語句。通過調用ToList<SomeEntity>(),您正在將整個事物讀入內存,然後使用LINQ to Objects進行過濾(並且由於在這種情況下查詢不會轉換爲SQL,因此運行查詢沒有任何問題)。

不幸的是,有沒有簡單的方法讓你的第一個查詢工作。如果您確實需要使用m1來篩選結果,則必須先將內容讀入內存。

這不僅僅是一個LINQ to nHibernate限制。 LINQ提供者使用表達式樹將代碼轉換爲另一種語言(在這種情況下,它試圖將C#代碼轉換爲與LINQ to SQL和實體框架相同的SQL語句)。

+3

這是正確的。然而,NHibernate 3 **不允許你擴展LINQ提供者以支持任何方法調用(當然,你必須知道如何從中創建一個HQL樹)。見http://fabiomaulo.blogspot.com/2010/07/nhibernate-linq-provider-extension.html – 2010-10-12 20:17:55

+0

@Diego Mijelshon:在NHibernate的3驚人的特點,非常感謝通知。 – 2010-10-13 06:14:22

1

推測方法m1沒有翻譯成SQL(至少,NHibernate的LINQ提供者不知道如何)。當你沒有ToList時,NHibernate試圖找出如何將m1轉換爲SQL。當你做ToList時,NHibernate不再扮演一個角色,它的LINQ到對象可以處理查詢。這對於啓用LINQ的ORM是特定的; LINQ到SQL和EF將遭受類似的命運。

1

我要說的是,你原來Q2查詢被翻譯成一個表達式樹,然後當NHibernate的嘗試來分析它,它發現該方法不是其實施的一部分。首先使用ToList()將查詢轉換爲集合使用List可以支持m1方法的LINQ功能。

0

我不知道NHibernate,但會工作嗎?

var q2 = q1.where (x => m1(x.prop2) == "def");