2010-09-14 71 views
2

我創建的字符串類型的簡單擴展方法:擴展方法where子句

public static bool Contains(this string word, string[] values) 
{ 
    foreach(string s in values) 
    { 
     if(!word.Contains(s)) 
      return false; 
    } 

    return true; 
} 
現在

,我有一個LINQ查詢,看起來像這樣:

public static IEnumerable<ISearchable> Search(params string[] keywords) 
{ 
    XPQuery<Customer> customers = new XPQuery<Customer>(unitOfWork); // ** 
    var found = from c in customers 
       where c.Notes.Contains(keywords) 
       select c; 

    return found.Cast<ISearchable>(); 
} 

我在where子句中得到'方法不被支持'異常,如果我使用string.Contains方法,這將很好地工作。

我的擴展方法有什麼問題,或者我試圖在linq where子句中使用它嗎?

** XPQuery是一個devexpress組件,因爲這是我使用的ORM,它是它們的linq-to-xpo查詢對象。

回答

2

你的代碼是合法的C#,但它可能不支持你正在使用的框架。你可以代替試試這個:

where keywords.All(keyword => c.Notes.Contains(keyword)) 

我還建議您將方法重命名爲ContainsAllContainsAny區別。

+0

希望是讓我的Contains(string [] s)方法感覺像string.Contains(string s)的重載。此外,我使用您提供的內容獲得了相同的錯誤。似乎它可能是LINQ到XPO的問題,但我不知道如何確定。 – 2010-09-14 22:09:46

0

我不知道XPQuery,但我想它使用表達式樹並將其轉換爲其他語言(例如,像LINQ to SQL這樣可以生成SQL的東西)。問題是圖書館不知道你的擴展方法。它不知道應該用什麼相應的代碼(用目標語言)代替你的方法。

一般來說,像LINQ to SQL等框架都不支持在查詢中使用自定義方法 - 因爲它們不能在方法內部查看如何翻譯它,因此您必須直接使用支持的方法(標準LINQ操作符)對您的邏輯進行編碼。 Mark的解決方案顯示瞭如何做到這一點。

1

LINQ到XPO嘗試解析您的查詢表達式並將其轉換爲SQL(或任何它需要的),但它無法理解對您的自定義方法的調用。

通常,您需要重寫您的查詢以擺脫自定義方法(請參閱Mark的答案),或者您可以拆分查詢以獲取一些初步數據,然後使用LINQ-to-Objects選擇您的方法需要設置。前者通常在性能方面更好。