Erstellen Sie einen Ausdrucksbaum in c #

c# expression-trees linq

Frage

Ich versuche, eine dynamische Abfrage mithilfe von Ausdrucksbaumstrukturen in LINQ zu erstellen, um die folgende Abfrage darzustellen

WageConstIns.Where(WageConstIn => WageConstIn.Serialno.ToString().StartsWith("2800"));

Ich habe versucht, es so zu erstellen:

MemberExpression le1 = LinqExpression.Property(paramExp, "Serialno");
MethodCallExpression le2 = LinqExpression.Call(le1, typeof(string).GetMethod("ToString",  System.Type.EmptyTypes));
ConstantExpression le3 = LinqExpression.Constant("2800");
MethodCallExpression le4 = LinqExpression.Call(le2, typeof(string).GetMethod("StartsWith"));

Ich bekomme während der Laufzeit einen Fehler. Wie kann die obige Abfrage am besten mit Ausdrucksbäumen erstellt werden?

Akzeptierte Antwort

Der einfachste Weg wäre, es einfach als Expression<Func<...>> zu deklarieren

public static class Program {
    public static void Main() {
        Expression<Func<DummyClass, Boolean>> predicate = WageConstIn => WageConstIn.Serialno.ToString().StartsWith("2800");
    }
}

Aber wenn du es mit verschiedenen Expressions konstruieren willst ...

public static class Program {
    public static void Main() {
        var param = Expression.Parameter(typeof(DummyClass), "WageConstIn");
        var constValue = Expression.Constant("2800");

        // WageConstIn => WageConstIn.Serialno.ToString().StartsWith(...)
        var first = Expression.Lambda(
            parameters: param,
            body: Expression.Call(
                instance: Expression.Call(
                    instance: Expression.Property(param, "Serialno"),
                    methodName: "ToString",
                    typeArguments: null,
                    arguments: null
                ),
                methodName: "StartsWith",
                typeArguments: null,
                arguments: new[] { constValue }
            )
        );

        // WageConstIn => Convert.ToString(WageConstIn.Serialno).StartsWith(...)
        var second = Expression.Lambda(
            parameters: param,
            body: Expression.Call(
                instance: Expression.Call(
                    type: typeof(Convert),
                    methodName: "ToString",
                    typeArguments: null,
                    arguments: new[] { Expression.Property(param, "Serialno") }
                ),
                methodName: "StartsWith",
                typeArguments: null,
                arguments: new[] { constValue }
            )
        );
    }
}

Die meisten Leute [mit denen ich gesprochen habe], die die Domäne von Ausdrucksbäumen betreten, sind normalerweise mit der System.Linq.Dynamic Funktionalität zufrieden. (Das kann auf viele verschiedene Arten missbraucht werden.) Dieses Code-Snippet von purer Großartigkeit ist ein Teil des Visual Studio-Beispielcodes, der sich wahrscheinlich schon irgendwo auf Ihrer Festplatte versteckt.




Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Ist diese KB legal? Ja, lerne warum
Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Ist diese KB legal? Ja, lerne warum