2016-12-21 4 views
2

Je crée des expressions pour le framework d'entité lors de l'exécution et j'ai résolu tous les problèmes sauf la sélection d'une propriété d'un ICollection enfant.Expression.Call Aucune méthode 'Select' n'existe sur le type System.Collections.Generic.ICollection

Il est difficile de poster tout mon cadre mais voici ce que j'ai essayé.

var param = Expression.Parameter(typeof(TEntity), "w"); 
Expression.Property(entity, propertyName); 

w.Roles

var param = Expression.Parameter(typeof(TChild), "z"); 
Expression.Property(entity, propertyName); 

z.ApplicationRole.Name

Cette ligne génère l'erreur.

Expression.Call(property, "Select", null,(MemberExpression)innerProperty); 

C'est l'erreur.

Aucune méthode 'Select' existe sur le type « System.Collections.Generic.ICollection`1 [ApplicationUserRole]

C'est ce que je suis en train de produire de façon dynamique.

await context.Users.Where(c => c.Roles 
           .Select(x => x.ApplicationRole.Name) 
           .Contains("admin")) 
        .ToListAsync(); 

J'apprécierais n'importe qui qui pourrait aider.

+3

Select est une méthode d'extension dans l'espace de noms System.Linq, donc vous ne pouvez pas l'appeler directement sur l'objet de la réflexion. Voir: http://stackoverflow.com/questions/1452261/how-do-i-invoke-an-extension-method-using-reflection –

Répondre

3

Comme déjà mentionné dans le commentaire, Select n'est pas une méthode d'IColletion, c'est une méthode d'extension et vous ne pouvez pas appeler Select directement à partir de ICollection.

Vous pouvez créer SelectMethodInfo cette façon:

var selM = typeof(Enumerable) 
     .GetMethods() 
     .Where(x => x.Name == "Select") 
     .First().MakeGenericMethod(typeof(TEntity), typeof(string)); 

et votre expression, vous pouvez créer autant:

var selExpression = Expression.Call(null, selM, param , lambda); 

Important est que premier paramètre de Expression.Call est nul, Select est une extension statique méthode et il n'a aucune instance à appeler.

lambda hier est une expression de lamda de votre propriété Expression

var prop= Expression.Property(entity, propertyName); 
var lambda = Expression.Lambda(prop, param); 
+0

Je suis coincé sur le lamda. Je ne sais pas ce qu'est param. J'ai essayé beaucoup de choses, y compris cette Expression.Lambda (propriété, (MemberExpression) innerProperty); – MIKE

+0

J'ai compris. Merci beaucoup! var lambda = Expression.Lambda ((MemberExpression) innerProperty, innerParam); – MIKE