How can I make Linq extension method available for the entities?

c# entity-framework entity-framework-6 extension-methods linq

Question

I developed a technique that expandsSystem.Linq class. MyContainsAnyWord Instead of comparing one string to another, technique enables me to search all words in a string against another string.

This is the extension technique I created.Linq

public static class LinqExtension
{

    public static bool ContainsAnyWord(this string value, string searchFor)
    {
        if (!string.IsNullOrWhiteSpace(value) && !string.IsNullOrWhiteSpace(searchFor))
        {
            value = value.ToLower();

            IEnumerable<string> tags = StopwordTool.GetPossibleTags(searchFor);

            return tags.Contains(value);

        }

        return false;

    }

}

This add-on technique works well on anIEnumerable object. However, if I want to utilise it onIQueryable object I encounter the following error

LINQ to Entities does not recognize the method 'Boolean ContainsAnyWord(System.String, System.String)' method, and this method cannot be translated into a store expression.

The reason the next example works so well is because I am using a list.

using(var conn = new AppContext())
{

    var allUsers = conn.Users.GetAll().ToList();
    var foundUsers = allUsers.Where
    (
        user => 
               user.FirstName.ContainsAnyWord("Some Full Name Goes Here")
            || user.LastName.ContainsAnyWord("Some Full Name Goes Here")
    ).ToList();

}

However, the example below does not apply since I am dealing withIQueryable It causes the mistake I mentioned before.

using(var conn = new AppContext())
{

    var allUsers = conn.Users.Where
    (
        user => 
            user.FirstName.ContainsAnyWord("Some Full Name Goes Here") 
         || user.LastName.ContainsAnyWord("Some Full Name Goes Here")
    ).ToList();

}

How can I resolve this problem and make this technique accessible toIQueryable object?

UPDATED

Based on the feedback I got below, I tried to implement this usingIQueryable as such

    public static IQueryable<T> ContainsAnyWord<T>(this IQueryable<T> query, string searchFor)
    {
        if (!string.IsNullOrWhiteSpace(searchFor))
        {
            IEnumerable<string> tags = StopwordTool.GetPossibleTags(searchFor);

            return query.Where(item => tags.Contains(item));

        }

        return query;

    }

But this is also returning an error to me.

enter image description here

1
0
11/11/2016 12:08:56 AM

Accepted Answer

ZZZ_tmp
4
11/10/2016 10:52:34 PM

Popular Answer

You cannot use methods within the query expression since the Linq to Entities expression parser is unable to handle it. You can only actually create an extension method that accepts aIQueryable<T> instead of calling, internally construct the expression inside the function.Where(

This code, which is below, is entirely untested and was just an idea I had. However, you would have to take this action.

public static IQueryable<T> WhereContainsAnyWord<T>(this IQueryable<T> @this, Expression<Func<T, string>> selector, string searchFor)
{
    var tags = StopwordTool.GetPossibleTags(searchFor); //You might need a .ToArray() here.

    var selectedItems = @this.GroupBy(selector);
    var filteredItems = selectedItems.Where(selectedItem => tags.Contains(selectedItem.Key.ToLower()));
    var result = filteredItems.SelectMany(x => x);
    return result;
}

used as

using(var conn = new AppContext())
{

    var allUsers = conn.Users.WhereContainsAnyWord(user => user.FirstName, "Some Full Name Goes Here").ToList();

}

This version is simplified and not generic.

public static IQueryable<User> WhereContainsAnyWord(this IQueryable<User> @this, string searchFor)
{
    var tags = StopwordTool.GetPossibleTags(searchFor); //You might need a .ToArray() here.

    return @this.Where(user => tags.Contains(user.DisplayName.ToLower()));
}

used as

using(var conn = new AppContext())
{

    var allUsers = conn.Users.WhereContainsAnyWord("Some Full Name Goes Here").ToList();

}


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow