2016-05-22 3 views
0

J'ai des problèmes pour faire pivoter un générateur d'arbre d'expression que j'ai construit.Expression Tree Expression.Call Syntaxe

Essentiellement, je veux convertir ce qui suit à un arbre d'expression:

var res = myObjInstance.AnalysisResponseMeasures 
      .First(p => p.MeasureTypeId == 1).MeasureValue 

Jusqu'à présent, j'ai:

var propertyExp = Expression.Property(pe, "AnalysisResponseMeasures"); 
      var someParam = Expression.Parameter(typeof(AnalysisResponseMeasure), "p"); 
      var someParam2 = Expression.Parameter(typeof(AnalysisResponseMeasure), "p"); 
      var childPropExp = Expression.Equal(
        Expression.Property(someParam, "MeasureTypeId"), 
        Expression.Constant(1)); 

      var firstExp = Expression.Call(
      typeof(IEnumerable<AnalysisResponseMeasure>), 
      "First", 
      new[] { typeof(AnalysisResponseMeasure) }, 
      propertyExp, 
      Expression.Lambda(childPropExp, someParam2)); 

      var selectExp = Expression.Property(firstExp, "MeasureValue"); 

Mais, je reçois une erreur d'exécution indiquant que le type de IEnumerable<AnalysisResponseMeasure> n'a pas de méthode First.

J'ai clairement mes paramètres, mais je n'arrive pas à comprendre ce qui ne va pas. Toute aide sera très appréciée.

+1

Vous souhaitez appeler la méthode statique [Enumerable.First] (https://msdn.microsoft.com/en-us/library/bb291976 (v = vs.100) .aspx) –

+0

@JohanLarsson, merci. Je n'essaie pas d'appeler cette méthode statique. J'essaie d'appeler la méthode d'extension Linq d'abord avec un lambda. –

+0

C'est la méthode à laquelle je suis lié. –

Répondre

1

joué un peu, peut-être cela fonctionne pour vous:

var p = Expression.Parameter(typeof(AnalysisResponseMeasure), "p"); 
var prediacte = Expression.Lambda<Func<AnalysisResponseMeasure, bool>>(Expression.Equal(Expression.Property(p, "MeasureTypeId"), Expression.Constant(1)), p); 

var firstMethod = typeof(Enumerable).GetMethods(BindingFlags.Static | BindingFlags.Public) 
            .Single(m => m.Name == "First" && 
               m.GetParameters().Length == 2 && 
               m.GetParameters()[1].ParameterType.IsGenericType && 
               m.GetParameters()[1].ParameterType.GetGenericTypeDefinition() == typeof(Func<,>)) 
            .MakeGenericMethod(typeof(AnalysisResponseMeasure)); 
var foo = Expression.Parameter(typeof(Foo), "foo"); 
var first = Expression.Call(firstMethod, Expression.Property(foo, "AnalysisResponseMeasures"), prediacte); 
var measureValue = Expression.Property(first, "MeasureValue"); 
var yourExpression = Expression.Lambda<Func<Foo, double>>(measureValue, foo); 

Il est illisible, assurez-vous d'ajouter des tests unitaires.

+0

Vous pouvez obtenir les informations de méthode en plus de "type sécurisé" par: var firstMethod = ((MethodCallExpression) ((LambdaExpression) (((Expression >) (() => default (IEnumerable ). Premièrement (d => vrai))))). Corps) .Méthode; – MBoros

+0

I cargo cultivé: D –