EF extension method: “This function can only be in

2019-02-18 01:19发布

问题:

I have made an extension method to EF entities:

public static IEnumerable<T> WildcardSearch<T>(this IEnumerable<T> entity, 
                                                 string param, Func<T, 
                                                 string> selector)
{
    return entity.Where(l => SqlFunctions.PatIndex(param, selector(l)) > 0);
}

//exception: This function can only be invoked from LINQ to Entities.
result = context.FOO.WildcardSearch(id, x => x.Id).ToList();

I get the exception above if I try to use it.

However, if I run (what I assume) the very same code directly on my collection, it works as intented.

Why do I get the exception, and is there any way to fix this?

Similar threads suggest changing the type to IQueryable, but it doesn't seem to help.

//this works
result = context.FOO.Where(x => 
              SqlFunctions.PatIndex(id, x.Id) > 0).ToList();

回答1:

It needs to be IQueryable<T> and Expression<Func<...>>; unfortunately this means rebuilding the expression tree - for example:

public static IQueryable<T> WildcardSearch<T>(this IQueryable<T> entity,
    string param, Expression<Func<T, string>> selector)
{
    var lambda = Expression.Lambda<Func<T, bool>>(
        Expression.GreaterThan(
            Expression.Call(
                typeof(SqlFunctions), "PatIndex", null,
                Expression.Constant(param, typeof(string)),
                selector.Body),
            Expression.Constant(0)),
        selector.Parameters);
    return entity.Where(lambda);
}