我学习如何构建像
这样的简单表达式c=>c.code=='XXX';
我通过以下方法创建这些表达式:
public static Expression<Func<T, bool>> BuildStringEqualLambda(string propertyName, string propertyValue)
{
ParameterExpression parameterExp = Expression.Parameter(typeof(T), "type");
Expression propertyExp = parameterExp;
foreach (var property in propertyName.Split('.'))
{
propertyExp = Expression.PropertyOrField(propertyExp, property);
}
Expression right = Expression.Constant(propertyValue);
Expression e1 = Expression.Equal(propertyExp, right);
return Expression.Lambda<Func<T, bool>>(e1, new ParameterExpression[] { parameterExp });
}
我想我可以构建表达式
o=>o.code=='XXX' || c.name=='XXX'
但我不知道如何构建方法Any。
由于
答案 0 :(得分:1)
应该是这样的:
public static Expression<Func<T, bool>> BuildStringEqualLambda<T>(params Tuple<string, string>[] propertyNameValues)
{
if (propertyNameValues == null || propertyNameValues.Length == 0)
{
throw new ArgumentException(nameof(propertyNameValues));
}
ParameterExpression parameterExp = Expression.Parameter(typeof(T), "type");
Expression body = null;
foreach (var propertyNameValue in propertyNameValues)
{
Expression propertyExp = parameterExp;
foreach (var property in propertyNameValue.Item1.Split('.'))
{
propertyExp = Expression.PropertyOrField(propertyExp, property);
}
Expression right = Expression.Constant(propertyNameValue.Item2);
Expression eq = Expression.Equal(propertyExp, right);
body = body == null ? eq : Expression.OrElse(body, eq);
}
return Expression.Lambda<Func<T, bool>>(body, new ParameterExpression[] { parameterExp });
}
您可以使用一些有趣的LINQ和Aggregate
来减少行数,但它可能是不可取的。
最后,您使用Expression.OrElse
(不 Expression.Or
|
!)并处理第一个元素案例。
使用它像:
var exp = BuildStringEqualLambda(
Tuple.Create("prop1", "value1"),
Tuple.Create("prop2", "value2"),
Tuple.Create("prop3", "value3")
);
使用一些LINQ和Aggregate
(对于那些在没有LINQing的情况下无法生存的人)(请注意,虽然我不会使用LINQed版本的代码......但这是相当的不可读...... Enumerable.Aggregate
是可怕的&#34;):
public static Expression<Func<T, bool>> BuildStringEqualLambda<T>(params Tuple<string, string>[] propertyNameValues)
{
if (propertyNameValues == null || propertyNameValues.Length == 0)
{
throw new ArgumentException(nameof(propertyNameValues));
}
ParameterExpression parameterExp = Expression.Parameter(typeof(T), "type");
Expression body = propertyNameValues
.Select(x => BuildEqualityExpression<T>(parameterExp, x.Item1, x.Item2))
.Aggregate((acc, x) => Expression.OrElse(acc, x));
return Expression.Lambda<Func<T, bool>>(body, new ParameterExpression[] { parameterExp });
}
private static Expression BuildEqualityExpression<T>(ParameterExpression parameterExp, string propertyName, string propertyValue)
{
Expression propertyExp = propertyName
.Split('.')
.Aggregate((Expression)parameterExp, (acc, x) => Expression.PropertyOrField(acc, x));
Expression right = Expression.Constant(propertyValue);
Expression eq = Expression.Equal(propertyExp, right);
return eq;
}