2010-04-27 7 views
8

J'essaye de construire une expression lambda, contenant deux affectations (comme indiqué plus bas), que je peux ensuite passer à une méthode Queryable.Select(). J'essaye de passer une variable de chaîne dans une méthode, puis j'utilise cette variable pour construire l'expression lambda afin que je puisse l'utiliser dans une requête LINQ Select. Mon raisonnement est que j'ai une source de données SQL Server avec de nombreux noms de colonnes, je crée une application de cartographie qui permettra à l'utilisateur de sélectionner, en tapant dans le nom de la colonne, la colonne de données qu'ils veulent pour voir dans l'axe y de mon tableau, avec l'axe des x étant toujours le DateTime. Par conséquent, ils peuvent essentiellement choisir les données qu'ils représentent par rapport à la valeur DateTime (c'est une application de type entrepôt de données).Expression lambda à utiliser dans la requête Select()

je, par exemple, une classe pour stocker les données récupérées dans, et donc utiliser comme source graphique de:

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

Je (purement expérimentalement) construit un arbre d'expression pour la clause Where en utilisant la valeur de chaîne et qui fonctionne très bien:

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

Cependant ...... J'ai essayé une approche similaire pour l'instruction Select, mais je ne peux pas le faire travailler comme je l'ai besoin Select() pour X et Valeurs Y de la classe AnalysisChartSource, comme suit:Comment diable puis-je construire un tel arbre d'expression ... ou ... de manière plus précise ... .. y at-il un moyen plus facile que j'ai manqué complètement?

Répondre

15

Je trouve que la meilleure façon d'élaborer des arborescences d'expression est de voir ce que fait le compilateur C#. Voici donc un programme complet:

using System; 
using System.Linq.Expressions; 

public class Foo 
{ 
    public int X { get; set; } 
    public int Y { get; set; } 
} 

class Test 
{ 
    static void Main() 
    { 
     Expression<Func<int, Foo>> builder = 
      z => new Foo { X = z, Y = z }; 
    } 
} 

Compile, ouvrez les résultats dans le réflecteur et définir l'optimisation de .NET 2.0. Vous vous retrouvez avec ce code généré pour la méthode principale:

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

Fondamentalement, je pense que Expression.MemberInit est ce que vous êtes après.

+0

Jon bonne idée. Je vous donnerais 100 votes pour cette solution! :-) – gsharp

+0

Jon, génial !! Merci beaucoup! Je suis d'accord avec gsharp, une bonne idée! - Reflector est mon nouvel ami :-) Merci encore – jameschinnock

+0

@GSharp, je vais vous aider avec cela: +1. – Steven