我在字符串类型上创建了一个简单的扩展方法:
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子句中得到'method not supported'异常,如果我使用string.Contains方法,它将正常工作。
我的扩展方法有什么问题,或者我是否试图在linq where子句中使用它?
** XPQuery是一个devexpress组件,因为那是我正在使用的ORM,它是它们的linq-to-xpo查询对象。
答案 0 :(得分:2)
您的代码是合法的C#,但您使用的框架可能不支持它。你可以试试这个:
where keywords.All(keyword => c.Notes.Contains(keyword))
我还建议您将方法重命名为ContainsAll
,以区别于ContainsAny
。
答案 1 :(得分:2)
我的猜测是,linq-to-xpo不支持包含就像linq-to-entities v1.0(EF)不支持包含但linq-to-sql确实支持它。
这是实体框架的解决方法,也许你可以尝试一下。 'Contains()' workaround using Linq to Entities?
答案 2 :(得分:1)
LINQ-to-XPO尝试解析您的查询表达式并将其转换为SQL(或其他任何需要的东西),但它无法理解对自定义方法的调用。
通常,您需要重写查询以摆脱自定义方法(请参阅Mark的答案),或者您可以拆分查询以获取一些初步数据,然后使用LINQ-to-Objects选择所需的用你的方法设置。前者通常表现更好。
答案 3 :(得分:0)
我不知道XPQuery
,但我认为它使用表达式树并将其翻译成其他语言(例如LINQ to SQL,它生成SQL)。问题是库不知道您的扩展方法。它不知道应该生成哪些相应的代码(在目标语言中)代替您的方法。
一般来说,LINQ to SQL等框架都不支持在查询中使用自定义方法 - 因为它们看不到方法的“内部”以查看如何翻译它,所以你必须直接编码您的逻辑使用支持的方法(标准LINQ运算符)。 Mark的解决方案展示了如何做到这一点。