Преобразование дерева выражений Linq, которое использует SqlMethods.Like () для использования с Entity Framework - PullRequest
0 голосов
/ 01 апреля 2010

Я недавно переключился с использования Linq на Sql на Entity Framework. Одна из вещей, с которой я действительно боролся, это получение универсального метода расширения IQueryable, который был построен для Linq to Sql для работы с Entity Framework. Этот метод расширения зависит от метода Like () класса SqlMethods, который специфичен для Linq и 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");

Есть ли эквивалентный способ сделать это с Entity Framework?

Заранее спасибо.

Ответы [ 3 ]

2 голосов
/ 23 апреля 2013

Метод 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?)));
1 голос
/ 01 апреля 2010
1 голос
/ 01 апреля 2010

Мне удалось найти хорошее решение здесь: http://www.codeproject.com/KB/aspnet/AspNetMVCandJqGrid.aspx

По сути, он использует метод "Contains" класса string вместо метода Like класса SqlMethods.

Условие выражения = Expression.Call (memberAccess, typeof (строка) .GetMethod ("Содержит"), Expression.Constant (ключевое слово));

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...