2010-04-01 39 views
0

我最近从使用Linq切换到Sql到实体框架。我一直在努力的一件事是获得一个通用的IQueryable扩展方法,该方法是为Linq to Sql与实体框架一起工作而构建的。这个扩展方法依赖于SqlMethods的Like()方法,它是Linq to Sql特有的。我真的很喜欢这种扩展方法,它允许我通过简单地传入一个属性名称(字符串)和一个查询子句(也作为字符串),在运行时在任何对象上动态构造一个Sql Like语句。这种扩展方法对于使用flexigrid或jqgrid等网格非常方便。这里是Sql的Linq版本(从本教程采取:http://www.codeproject.com/KB/aspnet/MVCFlexigrid.aspx):转换依赖SqlMethods.Like()用于实体框架的Linq表达式树

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

有了这个扩展方法,我可以简单地做到以下几点:

someList.Like( “名字”, “迈克” );

anotherList.Like(“ProductName”,“widget”);

有没有一种等同的方式来使用实体框架做到这一点?

在此先感谢。

回答

1

我能在这里找到一个很好的解决方案:http://www.codeproject.com/KB/aspnet/AspNetMVCandJqGrid.aspx

它主要采用“包含” string类,而不是SqlMethods类的方法一样的方法。表达式条件= Expression.Call(memberAccess,typeof(string).GetMethod(“Contains”),Expression.Constant(keyword));

2

的SQL方法PATINDEX提供相同的功能等。因此,您可以使用SqlFunctions.PatIndex方法。

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

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?))); 
+0

我只是想说你的第一个答案很棒。我一直在试图弄清楚如何对Linq EF运行一个简单的RegEx几天,让我在那里。谢谢。 – Tony 2014-06-23 20:06:22

+0

很高兴帮助:) – BG100 2014-06-24 11:30:42