我正在运行时为实体框架构建表达式,除了从子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);
这是错误。
类型上没有方法'选择' “System.Collections.Generic.ICollection`1 [ApplicationUserRole]
这就是我想要动态生成的内容。
await context.Users.Where(c => c.Roles
.Select(x => x.ApplicationRole.Name)
.Contains("admin"))
.ToListAsync();
我很感激能帮助的人。
答案 0 :(得分:4)
正如评论中已经提到的,Select
不是IColletion的方法,它是一种扩展方法,您无法直接从ICollection
调用Select
。
您可以通过以下方式创建MethodInfo
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
是一种静态扩展方法,并且不需要调用任何实例。
var prop= Expression.Property(entity, propertyName);
var lambda = Expression.Lambda(prop, param);
hier是您的属性Expression
ACTION_DOWN