Несколько условий в лямбда-выражениях во время выполнения C # - PullRequest
7 голосов
/ 21 марта 2010

Я хотел бы знать, как можно создать дерево выражений, введя более одного параметра

Пример:

dataContext.Users.Where(u => u.username == "Username" && u.password == "Password")

На данный момент код, который я сделал, былниже, но хотел бы сделать более общее в отношении того, является ли условие ИЛИ или И

public Func<TLinqEntity, bool> ANDOnlyParams(string[] paramNames, object[] values)
    {
        List<ParameterExpression> paramList = new List<ParameterExpression>();
        foreach (string param in paramNames)
        {
            paramList.Add(Expression.Parameter(typeof(TLinqEntity), param));
        }

        List<LambdaExpression> lexList = new List<LambdaExpression>();
        for (int i = 0; i < paramNames.Length; i++)
        {
            if (i == 0)
            {
                Expression bodyInner = Expression.Equal(
                                    Expression.Property(
                                        paramList[i], paramNames[i]),
                                        Expression.Constant(values[i]));
                lexList.Add(Expression.Lambda(bodyInner, paramList[i]));
            }
            else
            {
                Expression bodyOuter = Expression.And(
                                    Expression.Equal(
                                    Expression.Property(
                                    paramList[i], paramNames[i]),
                                    Expression.Constant(values[i])),
                                    Expression.Invoke(lexList[i - 1], paramList[i]));
                lexList.Add(Expression.Lambda(bodyOuter, paramList[i]));
            }
        }

        return ((Expression<Func<TLinqEntity, bool>>)lexList[lexList.Count - 1]).Compile();
    }

Спасибо

1 Ответ

2 голосов
/ 21 марта 2010

Expression.And - это неправильная вещь, используемая здесь, она побитовая и.Вы хотите AndAlso.

Кажется, что вы, кроме того, что уже знаете механизм построения дерева выражений.Так что вы действительно спрашиваете, как вы можете позволить вызывающей стороне вашего метода построения указать более сложный и гибкий способ объединения различных условий.

В конечном счете, для истинной гибкости вам нужен мини-язык запросов.Выполните синтаксический анализ языка для построения дерева выражений.

В краткосрочной перспективе вы можете обойтись гораздо более простым: списком примитивных выражений и флагом bool, указывающим, должны ли они сочетаться с && или ||.

Обновление - Я заметил, что вы фактически компилируете полученное выражение в реальный делегат.Это заставляет меня задаться вопросом, почему вы делаете это трудным путем в первую очередь.Почему бы просто не написать выражение в виде лямбды, как в вашем первоначальном примере?(Если вы используете Linq для SQL или EF, вам все равно не следует компилировать выражение.)

Обновление 2 - вам, вероятно, понадобится Dynamic Linq .

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