Expression.Call No method 'Select' exists on type System.Collections.Generic.ICollection

1k views Asked by At

I am building expressions for entity framework at run time and I have solved all problems except selecting a property from a child ICollection.

It is difficult to post my whole framework but here is what I have tried.

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

This line throws the error.

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

This is the error.

No method 'Select' exists on type 'System.Collections.Generic.ICollection`1[ApplicationUserRole]

This is what I am trying to produce dynamically.

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

I'd appreciate anyone who could help.

1

There are 1 answers

2
Maksim Simkin On BEST ANSWER

As already mentioned in comment, Select is not a method of IColletion, it's an extension method and you couldn't invoke Select directly from ICollection.

You could create Select MethodInfo this way:

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

and your Expression you could create as:

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

Important is, that first parameter of Expression.Call is null, Select is a static extension method and it don't have any instance to be called on.

lambda hier is a lamda expression from your property Expression

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