0

我想使用以下 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() 提出了以下内容,但它出错了,因为它不喜欢 .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);
4

2 回答 2

2

我懂了。类型参数 on Anyand Whereneed to be Employee, notIQueryable<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);
于 2013-05-29T22:29:42.903 回答
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());
于 2013-05-29T22:24:09.407 回答