2011-01-22 67 views
1
SomeObject.Where(p => FunctionOn(p.I)); 
<<>> 
public bool FunctionOn(int i){ 
    return (i == 1);} 
<<>> 
error message : The method FunctionOn is not supported 

,但爲什麼當我使用的,而不是參數號能正常工作?
如何使用Where運算符Linq中

SomeObject.Where(p => FunctionOn(1)); 

我想知道是否有實現Linq中的這段代碼的方式,因爲它給了我一個錯誤。
謝謝。

+0

你什麼錯誤? `FunctionOn`應該返回`bool`。 – 2011-01-22 11:53:03

+0

是的,像這種方法的錯誤不支持或類似的東西。 (我無法使用它) – Rawhi 2011-01-22 11:54:35

+0

編譯錯誤或運行時異常? – Elisha 2011-01-22 11:55:58

回答

2
SomeObject.Where(p => FunctionOn(p.I)); 

你說SomeObjectIQueryable。這讓我懷疑你沒有查詢內存中的集合(LINQ到對象),查詢應該可以在沒有任何問題的情況下成功,但是你可能會查詢更多的「動態」內容。爲了展示問題的緣故,我認爲我們在這裏處理LINQ到SQL ...但這種假設並不一定是必然爲真什麼,我想下面的解釋:

更新:你剛剛在您使用LINQ到MongoDB的評論說,所以下面應該適用於您的問題。

的東西像LINQ到SQL與您的查詢的問題不在於什麼是錯與FunctionOn判斷方法,或者你用Where操作相結合的方式。現在的問題在於,LINQ-to-SQL(或者您正在使用的任何LINQ提供程序)無法識別您的方法。它嘗試將LINQ表達式轉換爲在運行SQL查詢(這正是IQueryable是好的,畢竟!),但它不知道如何將轉換FunctionOn到SQL。

如果LINQ到SQL爲實現這一目標,就必須弄清楚你的方法做,然後找到一種方式來表達,作爲有效的SQL。這需要很多複雜和智慧。例如,它必須檢查你的方法,例如通過反編譯,然後重新編譯爲SQL。這顯然不適用於任何複雜的方法。假設您的FunctionOn方法包含對Debug.WriteLine的調用。沒有辦法將其轉換爲SQL查詢。

因此LINQ到SQL僅限於少數病例和表情,它知道如何處理。如果遇到任何其他的LINQ表達式,它會讓你知道,它不知道如何處理FunctionOn(即如何將其轉換爲SQL)說像,「的方法功能特徵不被支持。 「

一旦你寫你的查詢爲:

SomeObject.Where(p => p.I == 1); 

一切都應該很好地工作,因爲LINQ到SQL知道如何翻譯你的p.I == 1到SQL WHERE條款相應的相等測試。

2

您需要更具體和你實際上得到,然而,作爲一般指導錯誤,通常這會失敗,如果FunctionOn不能被翻譯成特定數據庫語言查詢(如果SomeObject是DB實體)或它不返回Where函數期望的布爾值。

0

這可能會實現,試試:

SomeObject.AsEnumerable().Where(p => FunctionOn(p.I)) 

它將對LINQ到實體和LINQ到SQL工作過!

爲什麼!怎麼樣?

因爲像stakx解釋。 IQueryable存儲您的表情。如果你看看它有一個Expression屬性,你在你的代碼編寫,然後LinqProvider然後將其轉化爲正確的事情,你的情況,這將是MongoDB的語法/ SQL IDK的docs for IQueryable,這 LINQ的?對於linq-to-sql,這將變成一個T-SQL表達式。所以沒有的SQL方式FunctionOn()。它可以神奇地調用你用C#編寫的SQL函數嗎?不!現在

IEnumerable是內存中的對象集合。當你說AsEnumerable()時,你得到內存中的對象,那麼當你做時Where(x=> func(x)) Linq-To-Objects可以處理它沒問題。

像@Will上的評論正確地說,這得到每一個對象到內存,然後查詢它。有時,它可能不是你想要做什麼,但我希望你能理解爲什麼代碼不工作,如果你還需要是八九不離十一個解決方法

希望它可以給你的我幾周前在觀看很多channel9 Linq視頻時發現了同樣的見解。 =)

0

正如其他人提及的,你的FunctionOn方法沒有由數據源直接平移。

但是,可能有變通的辦法 - 大你正在做一個比較,這取決於你需要做什麼樣的比較,以及如何。

相反,如果你創建一個擴展方法,這需要一個IQueryable<T>並返回IQueryable<T>你可以直接寫你的表達。

這可以讓您重新使用複雜的表達式。您還應該能夠與參考數據列表進行比較 - 但是您需要注意,此比較列表不會超過數據源允許的參數。

例子:

static void Main(string[] args) 
{ 


    var data = new List<Customer> 
       { 
        new Customer {Id = 1, Name = "Anna"}, 
        new Customer {Id = 2, Name = "Bob"}, 
        new Customer {Id = 3, Name = "Claire"} 
       }; 



    var result = data.AsQueryable().TestCustomer(); 




} 

private static IQueryable<Customer> TestCustomer(this IQueryable<Customer> source) 
{ 
    return source.Where(x => x.Id > 1); 
} 


public class Customer 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
}