我想使用以下API生成表达式树:
var managers = dataContext.Employees.Where(e => e.Subordinates.Any());
此外,如何生成表达式树来执行此操作:
var managedEmployees = managers.ToDictionary(key => key.Manager, value => value.Subordinates.Select(s => s.FullName));
到目前为止,我已经为.Where()提出了以下内容,但它错误,因为它不喜欢new Type[] { typeof(Func<Employee, IEnumerable<Employee>>) }
中的类型参数。
ParameterExpression employeesParameter = Expression.Parameter(typeof(Employee), "e");
MemberExpression subordinatesProperty = Expression.Property(employeesParameter, typeof(Employee).GetProperty("Subordinates"));
MethodCallExpression hasSubordinates = Expression.Call(typeof(Enumerable),
"Any",
new Type[] { typeof(Employee) },
subordinatesProperty);
LambdaExpression whereLambda = Expression.Lambda(hasSubordinates, employeesParameter);
MethodCallExpression whereExpression = Expression.Call(typeof(Queryable),
"Where",
new Type[] { typeof(Func<Employee, IEnumerable<Employee>>) },
dataContext.Employees.AsQueryable(),
whereLambda);
答案 0 :(得分:1)
Any
和Where
上的类型参数需要为Employee
,而不是IQueryable<Employee>
或IEnumerable<Employee>
,因为它只是查找类型参数,而不是实际类型。我相信您还需要Expression.Constant(dataContext.Employees)
而不是直接dataContext.Employees
。
ParameterExpression employeesParameter = Expression.Parameter(typeof(Employee), "e");
MemberExpression subordinatesProperty = Expression.Property(employeesParameter, typeof(Employee).GetProperty("Subordinates"));
MethodCallExpression hasSubordinates = Expression.Call(typeof(Enumerable),
"Any",
new Type[] { typeof(Employee) },
subordinatesProperty);
LambdaExpression whereLambda = Expression.Lambda(hasSubordinates, employeesParameter);
MethodCallExpression whereExpression = Expression.Call(typeof(Queryable),
"Where",
new Type[] { typeof(Employee) },
Expression.Constant(dataContext.Employees),
whereLambda);
答案 1 :(得分:0)
要为Any
致电MemberExpression
,您应该这样做
ParameterExpression employeesParameter = Expression.Parameter(typeof(Employee), "e");
MemberExpression subordinatesProperty = Expression.Property(employeesParameter, typeof(Employee).GetProperty("Subordinates"));
var mi = typeof(Enumerable).GetMethods().First(x => x.Name == "Any" && x.GetParameters().Length == 1);
mi = mi.MakeGenericMethod(typeof (bool));
var hasSubordinates = Expression.Call(mi, subordinatesProperty);
和Where
var lambda = Expression.Lambda<Func<Employee, bool>>(hasSubordinates, employeesParameter);
var res = i.Where(lambda.Compile());