Frage

Ich versuche, eine statische Funktion oder zwei Ausdrücke zu schreiben, aber empfange die folgende Fehlermeldung:

  

Der Parameter 'item' ist in ihrem Umfang nicht.

     

Beschreibung: Eine nicht behandelte Ausnahme   während der Ausführung des aufgetretenen   aktuelle Web-Anfrage. Bitte lesen Sie die   Stack-Trace für weitere Informationen über   der Fehler und wo sie ihren Ursprung in   der Code.

     

Ausnahmedetails:   System.InvalidOperationException: Die   Parameter 'item' ist in ihrem Umfang nicht.

die Methode:

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);
}

Bearbeiten : Mehr Details Hinzufügen

Die Ausdrücke werden im Folgenden aus dem Verfahren kommen, ODER-Verknüpfung, die ganz gut ausführen. wenn es einen besseren Weg zu oder die Ergebnisse ist bin ich ganz Ohr. Auch ich weiß nicht, wie viele werden im Voraus ODER-verknüpft.

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);
            }

Bearbeiten : Hinzufügen von noch mehr Informationen

Alternativ gibt es einen besseren Weg, um einen oder zu tun? Derzeit ist die .Where (Constraint) funktioniert gut, wo Zwang vom Typ Expression ist>. Wie kann ich tun, wo (constraint1 oder constraint2) (die Einschränkung n-ten)

Vielen Dank im Voraus!

War es hilfreich?

Lösung

Das Problem ist, dass der Ausdruck, den Sie in den Verfahren OrExpressions sind die Schaffung der Körper der beiden Ausdrücke wieder verwendet. Diese Stellen werden Verweise auf ihre eigene Parameterexpression enthalten, die in Filterexpression definiert wurde.

Ein Update wäre die linken und rechten Teile neu zu schreiben, die neue Parameterexpression zu verwenden. Oder die ursprüngliche Parameterexpression passieren entlang. Es ist nicht, weil die beiden Parameterexpression haben den gleichen Namen, dass sie die gleichen Parameter darstellen.

Andere Tipps

Wie bereits angedeutet, Sie diese sehr schön finden (in Betrieb) Code

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);
}

, die Sie an Ihre Bedürfnisse anpassen können und welche nicht gebunden (IMHO) zu LINQ.

Ich bin mir nicht sicher über die richtigen Begriffe hier, aber im Grunde Ausdruck Parameter sind nicht gleichwertig, auch wenn sie die gleichen Namen haben.

Das bedeutet, dass

var param1 = Expression.Parameter(typeof(T), "item");
var param2 = Expression.Parameter(typeof(T), "item");

param1 != param2

param1 und param2 werden nicht dasselbe sein, wenn in einem Ausdruck verwendet.

Der beste Weg, damit umzugehen ist vorne für Ihren Ausdruck einen Parameter erstellen, und dann an alle Helferfunktionen übergibt es, die die Parameter benötigen.

EDIT: Auch, wenn Sie dynamisch sind versuchen, wo Klauseln in LINQ zu komponieren, könnten Sie geben PredicateBuilder versuchen.

Für diejenigen, die diese Seite durch eine Suchmaschine gefunden und wird verwenden die PredicateBuilder von Ben & Joe Albahari , watch out, da es nicht mit dem Rahmen Entity arbeiten .

Versuchen Sie diese feste Version statt.

Fabrizio Lösung kam es auch als gut für mich, aber da ich zwei Ausdrücke zu kombinieren versuche, die als Linq 2 SQL-Abfrage ausgeführt werden würde, dachte ich es eher im Speicher ausgeführt werden würde, als der SQL-Server.

Ich schrieb -. Linq to SQL- erkennt, dass der Aufruf einer Lambda-Ausdruck ist und erzeugt somit noch optimiert SQL

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top