【问题标题】:Converting a Linq expression tree that relies on SqlMethods.Like() for use with the Entity Framework转换依赖 SqlMethods.Like() 的 Linq 表达式树以与实体框架一起使用
【发布时间】:2010-04-01 05:10:27
【问题描述】:

我最近从使用 Linq 切换到 Sql 到 Entity Framework。我一直在努力解决的一件事是获得一个通用的 IQueryable 扩展方法,该方法是为 Linq to Sql 构建的,可以与实体框架一起使用。此扩展方法依赖于 SqlMethods 的 Like() 方法,该方法是 Linq to Sql 特定的。我真正喜欢这个扩展方法的地方在于,它允许我在运行时在任何对象上动态构造一个 Sql Like 语句,只需传入一个属性名称(作为字符串)和一个查询子句(也作为字符串)。这种扩展方法对于使用像 flexigrid 或 jqgrid 这样的网格非常方便。这是 Linq to Sql 版本(取自本教程: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);
    }

使用这种扩展方法,我可以简单地做到以下几点:

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

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

实体框架有没有等效的方法?

提前致谢。

【问题讨论】:

    标签: c# linq linq-to-sql entity-framework linq-to-entities


    【解决方案1】:

    SQL 方法 PATINDEX 提供与 LIKE 相同的功能。因此,您可以使用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?)));
    

    【讨论】:

    • 我只想说你的第一个答案太棒了。几天来,我一直试图弄清楚如何针对 Linq EF 运行一个简单的 RegEx,这让我到了那里。谢谢。
    【解决方案2】:

    【讨论】:

    • 可查询搜索看起来很棒。感谢分享链接。
    【解决方案3】:

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

    它本质上使用的是字符串类的“Contains”方法,而不是SqlMethods类的Like方法。

    表达式条件 = Expression.Call(memberAccess, typeof(string).GetMethod("Contains"), Expression.Constant(keyword));

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-15
      • 1970-01-01
      • 1970-01-01
      • 2023-03-27
      相关资源
      最近更新 更多