それはのようなものでなければなりません:
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 });
}
おそらく、行の数を減らすためにAggregate
でいくつかの面白いLINQを使用することができますが、それはundebuggableだろう。最後に
あなたがExpression.OrElse
を使う(|
あるないExpression.Or
!)、あなたが最初の要素のケースを扱います。
のようにそれを使用します。
いくつかのLINQを使用して
var exp = BuildStringEqualLambda(
Tuple.Create("prop1", "value1"),
Tuple.Create("prop2", "value2"),
Tuple.Create("prop3", "value3")
);
とAggregate
(すべてをリンチンなしでは生きられない人のために)(私が今までのコードのLINQedバージョンを使用していないだろうしながら、ということに注意してください。.. 。それは)Enumerable.Aggregate
は "ひどい" です...かなり読めないです:
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;
}
見https://stackoverflow.com/questions/34730432/how-do-i-build-expression-call-for-を取りますany-method-with-generic-parameter –