开发者

Converting a Linq expression tree that relies on SqlMethods.Like() for use with the Entity Framework

I recently switched from using Linq to Sql to the开发者_Go百科 Entity Framework. One of the things that I've been really struggling with is getting a general purpose IQueryable extension method that was built for Linq to Sql to work with the Entity Framework. This extension method has a dependency on the Like() method of SqlMethods, which is Linq to Sql specific. What I really like about this extension method is that it allows me to dynamically construct a Sql Like statement on any object at runtime, by simply passing in a property name (as string) and a query clause (also as string). Such an extension method is very convenient for using grids like flexigrid or jqgrid. Here is the Linq to Sql version (taken from this tutorial: http://www.codeproject.com/KB/aspnet/MVCFlexigrid.aspx):

    public static IQueryable<T> Like<T>(this IQueryable<T> source,
                  string propertyName, string keyword)
    {
        var type = typeof(T);
        var property = type.GetProperty(propertyName);
        var parameter = Expression.Parameter(type, "p");
        var propertyAccess = Expression.MakeMemberAccess(parameter, property);
        var constant = Expression.Constant("%" + keyword + "%");
        var like = typeof(SqlMethods).GetMethod("Like",
                   new Type[] { typeof(string), typeof(string) });
        MethodCallExpression methodExp =
              Expression.Call(null, like, propertyAccess, constant);
        Expression<Func<T, bool>> lambda =
              Expression.Lambda<Func<T, bool>>(methodExp, parameter);
        return source.Where(lambda);
    }

With this extension method, I can simply do the following:

someList.Like("FirstName", "mike");

or

anotherList.Like("ProductName", "widget");

Is there an equivalent way to do this with Entity Framework?

Thanks in advance.


The SQL method PATINDEX provides the same functionality as LIKE. Therefore, you can use the SqlFunctions.PatIndex method.

.Where(x => SqlFunctions.PatIndex("%123%ABC", x.MySearchField) > 0)

or

var miSqlPatIndex = typeof(SqlFunctions).GetMethod(
    "PatIndex", 
    BindingFlags.Public | BindingFlags.Static | BindingFlags.IgnoreCase, 
    null, 
    new Type[] { typeof(string), typeof(string) }, 
    null);                        
expr = Expression.GreaterThan(
    Expression.Call(
        miSqlPatIndex, 
        new Expression[] { Expression.Constant("%123%ABC"), MySearchField }),
        Expression.Convert(Expression.Constant(0), typeof(int?)));


You could consider looking at this:

http://naspinski.net/post/Universal-IQueryable-Search-Version-2-with-Reflection.aspx


I was able to find a good solution here: http://www.codeproject.com/KB/aspnet/AspNetMVCandJqGrid.aspx

It essentially uses the "Contains" method of the string class instead of the Like method of the SqlMethods class.

Expression condition = Expression.Call(memberAccess, typeof(string).GetMethod("Contains"), Expression.Constant(keyword));

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜