Estoy intentando construir un árbol de expresiones mediante programación.Excepción utilizando los métodos de expresión OrElse y AndAlso
que tengo en la entrada, una lista de clases de condición que tienen la siguiente forma:
public class Filter
{
public string field { get; set; }
public string operator { get; set; }
public string value { get; set; }
}
Cuando construyo el objeto Expression
creo una Expression
para cada condición de la siguiente manera
foreach (Filter sf in rules) {
Expression ex = sf.ToExpression(query);
if (mainExpression == null) {
mainExpression = ex;
}
else {
if (logicalCondition == "AND") {
mainExpression = Expression.And(mainExpression, ex);
}
else if (logicalCondition == "OR") {
mainExpression = Expression.Or(mainExpression, ex);
}
}
}
El método Filter.ToExpression() se implementa así
public override Expression ToExpression(IQueryable query) {
ParameterExpression parameter = Expression.Parameter(query.ElementType, "p");
MemberExpression memberAccess = null;
foreach (var property in field.Split('.'))
memberAccess = MemberExpression.Property(memberAccess ?? (parameter as Expression), property);
ConstantExpression filter = Expression.Constant(Convert.ChangeType(value, memberAccess.Type));
WhereOperation condition = (WhereOperation)StringEnum.Parse(typeof(WhereOperation), operator);
LambdaExpression lambda = BuildLambdaExpression(memberAccess, filter, parameter, condition, value);
return lambda;
}
Todo funciona cuando tengo una sola condición, pero cuando intento de combinar las expresiones que utilizan uno de los And
, Or
, AndAlso
, OrElse
métodos estáticos recibo un InvalidOperationException
que dice:
El operador binario o no se define para los tipos 'System.Func
2[MyObject,System.Boolean]' and 'System.Func
2 [MyObject, System.Boolean]'.
Me estoy poniendo un poco confundido. ¿Puede alguien explicar mejor los motivos de la excepción y sugerir una solución?
Muchas gracias!
Hola, gracias por tu respuesta. No puedo usar código de terceros para resolver este problema. ¿Podría explicar mejor cuál sería la forma de hacerlo manualmente? ¡Gracias de nuevo! – Lorenzo
@Lorenzo Seguro, he agregado un programa basado en las dos expresiones que utilicé como ejemplo. – hvd
Hola, he intentado implementar su solución. Comprendí que el 'ExpressionVisitor' proviene de las fuentes de LinqKit y pude ver cómo funciona. La pregunta ahora es: ¿de dónde viene el método 'Zip' de' IEnumerable '? Estoy usando .NET 3.5 y no puedo encontrar ese método :( –
Lorenzo