Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > LINQ (Language-Integrated Query) > Динамическое создание where


Автор: Greeneyed 24.2.2011, 16:08
Есть запрос 


Код

var values = db.ValueOfSystemReference.Where(v => v.idAttribute == attr.id 
                                                                            && SqlMethods.Like( v.Value.ToString(), "%"+ cityName.ToString() + "%" )
                                                                            ).ToList();


Он находит все города, которые LIKE '%cityName%'.

А мне нужно сделать, что он сравнивал с несколькими именами.  LIKE '%cityNam1e%' OR  LIKE '%cityName2%' OR  LIKE '%cityName3%' и т.д.
Количество имен, естественно, заранее не известно. Есть Expression Trees, с помощью которых можно сделать динамически лямбда-выражения, но как этим чудом пользоваться я не понял.

Автор: jonie 25.2.2011, 08:26
что насчет DLINQ ?

Автор: Greeneyed 25.2.2011, 08:57
Не пробовал. И, честно говоря, не знаю как его прикрутить и юзать.
В общем нашел вот такой класс.

Код

 public static class PredicateBuilder
    {
        public static Expression<Func<T, bool>> True<T>() { return f => true; }
        public static Expression<Func<T, bool>> False<T>() { return f => false; }

        public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> expr1,
                                                            Expression<Func<T, bool>> expr2)
        {
            var invokedExpr = Expression.Invoke(expr2, expr1.Parameters.Cast<Expression>());
            return Expression.Lambda<Func<T, bool>>
                  (Expression.OrElse(expr1.Body, invokedExpr), expr1.Parameters);
        }

        public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> expr1,
                                                             Expression<Func<T, bool>> expr2)
        {
            var invokedExpr = Expression.Invoke(expr2, expr1.Parameters.Cast<Expression>());
            return Expression.Lambda<Func<T, bool>>
                  (Expression.AndAlso(expr1.Body, invokedExpr), expr1.Parameters);
        }
    }


Которым пользоваться надо вот так

Код

                        var predicate = PredicateBuilder.False<ValueOfSystemReference>();
                        foreach (var word in wordsOfCityName)
                        {
                            predicate = predicate.Or(v => SqlMethods.Like(v.Value.ToString(), "%" + word + "%"));
                        }
                        predicate = predicate.And(v => v.idAttribute == attr.id);
                        
                        var values = db.ValueOfSystemReference.Where(predicate);


Добавлено через 25 секунд
Так что тему можно закрывать.

Автор: v00d00 10.6.2011, 00:43
Не забываем на внутренних экспрешенах вызывать Expand()
Решение серверное. На сильвере будет падать, потому что рефлексией смотрят приватные поля.(?)

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)