Несколько условий в лямбда-выражениях во время выполнения C#

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

пример:

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 ответов


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

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

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

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

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

обновление 2 - что вам, вероятно, нужно это Динамический Linq.