Несколько условий в лямбда-выражениях во время выполнения 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.