Expression.Or, el parámetro 'item' no está en el alcance

c# expression expression-trees linq

Pregunta

Estoy tratando de escribir una función estática para O dos expresiones, pero recibo el siguiente error:

El parámetro 'item' no está en alcance.

Descripción: se produjo una excepción no controlada durante la ejecución de la solicitud web actual. Revise el seguimiento de la pila para obtener más información sobre el error y dónde se originó en el código.

Detalles de la excepción: System.InvalidOperationException: el parámetro 'item' no está dentro del alcance.

el método:

public static Expression<Func<T, bool>> OrExpressions(Expression<Func<T, bool>> left, Expression<Func<T, bool>> right)
{
    // Define the parameter to use
    var param = Expression.Parameter(typeof(T), "item");

    var filterExpression = Expression.Lambda<Func<T, bool>>
         (Expression.Or(
             left.Body,
             right.Body
          ), param);
    // Build the expression and return it
    return (filterExpression);
}

edición : añadiendo más información

Las expresiones que vienen o vienen del método a continuación, que se ejecutan bien. Si hay una mejor manera de hacerlo o los resultados soy todo oídos. Además, no sé cuántos están siendo o de antemano.

public static Expression<Func<T, bool>> FilterExpression(string filterBy, object Value, FilterBinaryExpression binaryExpression)
{
    // Define the parameter to use
    var param = Expression.Parameter(typeof(T), "item");

    // Filter expression on the value
    switch (binaryExpression)
    {
        case FilterBinaryExpression.Equal:
            {
                // Build an expression for "Is the parameter equal to the value" by employing reflection
                var filterExpression = Expression.Lambda<Func<T, bool>>
                    (Expression.Equal(
                        Expression.Convert(Expression.Property(param, filterBy), typeof(TVal)),
                        Expression.Constant(Value)
                     ),
                    param);
                // Build the expression and return it
                return (filterExpression);
            }

Edición : añadiendo aún más información

Alternativamente, ¿hay una mejor manera de hacer un o? Actualmente, la .Where (restricción) funciona bien donde la restricción es de tipo Expresión>. ¿Cómo puedo hacer dónde? (Restricción1 o restricción2) (a la restricción n'th)

¡Gracias por adelantado!

Respuesta aceptada

El problema es que la expresión que está creando en el método OrExpressions reutiliza el cuerpo de las dos expresiones. Esos cuerpos contendrán referencias a su propia ParameterExpression que se ha definido en FilterExpression.

Una solución sería volver a escribir las partes izquierda y derecha para usar la nueva ParameterExpression. O pasar la ParameterExpression original a lo largo. No es porque los dos ParameterExpression tienen el mismo nombre que representan el mismo parámetro.


Respuesta popular

Como ya se sugirió, aquí puede encontrar este código muy bueno (en funcionamiento)

public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> expr1, Expression<Func<T, bool>> expr2)
{
    var invokedExpr = Expression.Invoke(expr2, expr1.Parameters.Cast<Expression>());
    return Expression.Lambda<Func<T, bool>>(Expression.Or(expr1.Body, invokedExpr), expr1.Parameters);
}

que puede adaptarse a sus necesidades y que no está vinculado (IMHO) a LINQ.



Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow