开发者

Extension method in a where clause

I've created a simple extension method on the string type:

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

    return true;
}

now, I've got a linq query that looks like this:

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>();
}

I get a 'method not supported' exception on the where clause, which will work fine if I use the string.Contains method.

Is there something wrong with my extension method, or the way I'm trying to use it in a linq where clause?

** XPQuery is a devexpress component, as that's the ORM I'm using, which is their linq-to-xpo query object.


My guess is that there linq-to-xpo doesn't suppor the contain just like linq-to-entities v1.0 (EF) didn't support contain but linq-to-sql did support it.

Here was the workaround for entity framework, maybe you can try it. 'Contains()' workaround using Linq to Entities?


Your code is legal C# but it's probably not supported by the framework you are using. You could try this instead:

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

I'd also suggest that you rename your method to ContainsAll to distinguish it from ContainsAny.


LINQ-to-XPO tries to parse your query expression and translate it into SQL (or whatever it needs), but it can't understand a call to your custom method.

In general, either you need to rewrite your query to get rid of the custom method (see Mark's answer), or you can split a query to fetch some preliminary data and then, using LINQ-to-Objects, select the required set with your method. The former is usually better performance-wise.


I don't know about XPQuery, but I suppose that it uses expression tree and translates it to some other language (e.g. something like LINQ to SQL, which generates SQL). The problem is that the library does not know about your extension method. It does not know what corresponding code (in the target language) should it generate in place of your method.

In general, none of the frameworks like LINQ to SQL etc. do not support using custom methods in the query - because they cannot look "inside" the method to see how to translate it, so you'll have to directly encode your logic using supported methods (standard LINQ operators). The solution from Mark shows how to do this.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜