2010-04-27 5 views
8

Ich versuche einen Lambda-Ausdruck zu erstellen, der zwei Zuweisungen enthält (wie weiter unten gezeigt), die ich dann an eine Queryable.Select() -Methode übergeben kann.Lambda-Ausdruck, der in der Select() -Abfrage verwendet werden soll

Ich versuche, eine String-Variable in eine Methode übergeben und dann verwenden Sie diese Variable, um den Lambda-Ausdruck zu erstellen, so dass ich es in einer LINQ Select-Abfrage verwenden kann.

Meine Argumentation dahinter ist, dass ich eine SQL Server-Datenquelle mit vielen Spaltennamen habe, ich erstellen eine Charting-Anwendung, die den Benutzer ermöglicht, durch Eingabe der Spaltennamen, die tatsächliche Spalte der Daten, die sie wollen um in der Y-Achse meines Diagramms zu sehen, wobei die X-Achse immer die DateTime ist. Daher können sie im Wesentlichen auswählen, welche Daten sie gegenüber dem DateTime-Wert darstellen (es handelt sich um eine Data-Warehouse-App).

Ich habe zum Beispiel eine Klasse der abgerufenen Daten in, zu speichern und somit als Diagramm Quelle verwenden:

public class AnalysisChartSource 
{ 
    public DateTime Invoicedate { get; set; } 
    public Decimal yValue { get; set; } 
} 

Ich habe (rein Experimentier) baute einen Ausdrucksbaum für die Where-Klausel verwenden der String-Wert und das funktioniert gut:

public void GetData(String yAxis) 
{ 
    using (DataClasses1DataContext db = new DataClasses1DataContext()) 
    { 
     var data = this.FunctionOne().AsQueryable<AnalysisChartSource>(); 
     //just to get some temp data in.... 

     ParameterExpression pe = Expression.Parameter(typeof(AnalysisChartSource), "p"); 
     Expression left = Expression.MakeMemberAccess(pe, 
               typeof(AnalysisChartSource).GetProperty(yAxis)); 
     Expression right = Expression.Constant((Decimal)16); 
     Expression e2 = Expression.LessThan(left, right); 
     Expression expNew = Expression.New(typeof(AnalysisChartSource)); 

     LambdaExpression le = Expression.Lambda(left, pe); 

     MethodCallExpression whereCall = Expression.Call(
      typeof(Queryable), "Where", new Type[] { data.ElementType }, 
      data.Expression, 
      Expression.Lambda<Func<AnalysisChartSource, bool>>(e2, new ParameterExpression[] { pe })); 
    } 
} 

aber ...... ich habe einen ähnlichen Ansatz für die Select-Anweisung versucht, aber kann es nicht, wie ich das Wählen an der Arbeit() muß beide X zu füllen und Y-Werte der AnalysisChartSource-Klasse wie folgt:

.Select(c => new AnalysisChartSource 
{ Invoicedate = c.Invoicedate, yValue = c.yValue}).AsEnumerable(); 

Wie auf der Erde kann ich einen solchen Ausdruck Baum bauen ... .oder ... .possibly mehr auf den Punkt ... ..ist es einen einfacheren Weg, den ich völlig verpasst haben?

Antwort

15

Ich finde, dass der beste Weg, um herauszufinden, wie man Ausdrucksbäume erstellen ist zu sehen, was der C# -Compiler tut. So, hier ist ein komplettes Programm:

Kompilieren Sie das, öffnen Sie die Ergebnisse in Reflector und setzen Sie die Optimierung auf .NET 2.0. Sie enden für die Main-Methode mit diesem generierten Code auf:

ParameterExpression expression2; 
Expression<Func<int, Foo>> expression = 
    Expression.Lambda<Func<int, Foo>>(
    Expression.MemberInit(
     Expression.New((ConstructorInfo) methodof(Foo..ctor), new Expression[0]), 
     new MemberBinding[] { Expression.Bind((MethodInfo) methodof(Foo.set_X), 
          expression2 = Expression.Parameter(typeof(int), "z")), 
          Expression.Bind((MethodInfo) methodof(Foo.set_Y), 
              expression2) } 
    ), 
    new ParameterExpression[] { expression2 }); 

Grundsätzlich denke ich Expression.MemberInit ist das, was Sie nach.

+0

Jon großartige Idee. Ich würde Ihnen 100 Stimmen für diese Lösung geben! :-) – gsharp

+0

Jon, brilliant !! Vielen Dank in der Tat! Ich stimme mit gsharp überein, eine großartige Idee! - Reflektor ist mein neuer Freund :-) Danke nochmal – jameschinnock

+0

@GSharp, ich helfe dir dabei: +1. – Steven

Verwandte Themen