views:

65

answers:

4

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.

+2  A: 

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.

Mark Byers
The hope was to make my Contains(string[] s) method feel like an overload to string.Contains(string s). Additionally, I get the same error using what you've provided. Seems like it might be a problem in LINQ-to-XPO but I don't know how to be sure just yet.
SnOrfus
A: 

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.

Tomas Petricek
+2  A: 

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. http://stackoverflow.com/questions/374267/contains-workaround-using-linq-to-entities

pdiddy
+1  A: 

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.

Yacoder