2010-09-14 63 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选择您的方法需要设置。前者通常在性能方面更好。