2016-12-21 7 views
2

Я создаю выражения для структуры сущности во время выполнения, и я решил все проблемы, кроме выбора свойства из дочернего ICollection.Expression.Call Нет метода 'Select' существует в типе System.Collections.Generic.ICollection

Трудно опубликовать все мои рамки, но вот что я пробовал.

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

Эта линия бросает ошибку.

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

Это ошибка.

Ни один метод 'Select' не существует на типе «System.Collections.Generic.ICollection`1 [ApplicationUserRole]

Это то, что я пытаюсь произвести динамически.

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

Я буду благодарен всем, кто мог бы помочь.

+3

Select является метод расширения в System.Linq пространстве имен, так что вы не можете вызвать его непосредственно на объекте с отражением. См. Http://stackoverflow.com/questions/1452261/how-do-invoke-an-extension-method-using-reflection –

ответ

3

Как уже упоминалось в комментарии, Select не является методом IColletion, это метод расширения, и вы не могли вызывать Select непосредственно с ICollection.

Вы можете создать SelectMethodInfo таким образом:

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

и ваше выражение можно создать, как:

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

Важно то, что первый параметр Expression.Call имеет нулевое значение, Select статическое расширение метод, и у него нет никакого экземпляра, который должен быть вызван.

lambda Hier является выражение лямда из вашей собственности Expression

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

Я застрял на лампе. Я не знаю, какой параметр. Я пробовал много вещей, включая это выражение Expression.Lambda (свойство, (MemberExpression) innerProperty); – MIKE

+0

Получил это. Спасибо! var lambda = Expression.Lambda ((MemberExpression) internalProperty, internalParam); – MIKE