linq для динамических сущностей, где предложение в виде строки

Я хочу динамически фильтровать данные с помощью linq для сущностей, предоставляя строковое выражение для предложения where.

Например:

string filterExpr = "it.City='London'"
var ret1 = Contex.Customers.Where(filterExpr);

Как я могу сделать то же самое, но на этот раз для фильтрации данных, которые начинаются с некоторой строки?

если невозможно добиться с помощью строки, как я могу создать подходящее лямбда-выражение?

(Также для меня важно иметь возможность фильтровать по многим параметрам (ИЛИ / И))


person Mark A    schedule 25.05.2011    source источник


Ответы (4)


Я думаю, что вы, возможно, ищете Dynamic LINQ. Скотт Гатри опубликовал это:

http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx

Это не так быстро, как использование лямбда-синтаксиса, поскольку их нужно компилировать во время выполнения, но это может быть вашим ответом.

person Kevin McKelvin    schedule 25.05.2011

Public Shared Function getFilterStartsWith(Of T)(ByVal param As ParameterExpression, ByVal prop As MemberExpression, ByVal arg As Object) As Expression
    Dim mi As MethodInfo = GetType(String).GetMethod("StartsWith", New Type() {GetType(String)}, Nothing)
    Return Expression.Lambda(Of Func(Of T, Boolean))(LambdaExpression.[Call](prop, mi, Expression.Constant(arg, GetType(String))), param)
End Function

In C#:

public static Expression getFilterStartsWith<T>(ParameterExpression param, MemberExpression prop, object arg) {
    MethodInfo mi = typeof(string).GetMethod("StartsWith", new Type[] { typeof(string) }, null);
    return Expression.Lambda<Func<T, bool>>(LambdaExpression.Call(prop, mi, Expression.Constant(arg, typeof(string))), param);
}

Эту функцию я использую для startWith в недавно написанном мной решении. Это оказалось огромной проблемой, потому что вы не можете использовать переменную Type в качестве параметра в ctype или DirectCast в vb, и вы не можете выполнять сравнения linq для объекта и объекта того же типа, допускающего значение NULL.

person dtryan    schedule 25.05.2011
comment
Блин, VB даже более многословен, чем я думал. - person Etienne de Martel; 26.05.2011
comment
синтаксис c #, пожалуйста, если это не сложно - person Mark A; 26.05.2011

пожалуйста, попробуйте это:

var ret1 = contex.Customers.Where(x => x.it.City.StartsWith('l'));

HTH

person Raja    schedule 25.05.2011
comment
лямбда-выражения для победы! - person Nathan Tregillus; 26.05.2011
comment
но я объяснил, что не могу его использовать! Где не знает о x.it.City, потому что он получает свойство для заполнения во время выполнения - person Mark A; 26.05.2011
comment
На самом деле это не отвечает на вопрос, как динамически указать фильтр в строке. - person Brook; 26.05.2011
comment
ООП ... плохо ... не могли бы вы попробовать это: tring filterExpr = it.City как 'L%'. HTH - person Raja; 26.05.2011

Забудьте о «волшебных» строках, C # предназначен для строгой типизации. Так или иначе, у вас будет список, где лучше всего их строго типизировать.

    public class Veg
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public bool Fruit { get; set; }
    }

    enum Mode
    {
        One,
        Two,
        Three
    }

    static void Main()
    {
        Mode mode = Mode.One;

        var data = new List<Veg>
        {
            new Veg{Id = 1, Name = "Apple", Fruit = true},
            new Veg{Id = 2, Name = "Carrot", Fruit = false}
        };

        var dataSelect = data.Where(w => (mode == Mode.One && w.Fruit) || //only fruits
                                         (mode == Mode.Two && !w.Fruit) || //only not fruits
                                         (mode == Mode.Three)); //all of it
    }
person alexqc    schedule 05.03.2015