使用类型转换动态构建表达式树

时间:2015-09-06 06:02:59

标签: c# linq dynamic entity-framework-6 expression-trees

(编者):

我有我的班级:

public class Employee
{
    public int Id {get;set;}
    public string Name {get;set;}
}

public class ContractEmployee : Employee
{
    public int ContractMonth {get;set;}
}

public class Remuneration
{
    public int Id {get;set;}
    public Employee Employee {get;set;}
    public int Amount {get;set;}
}

我可以像这样查询合约月份(使用员工作为基本类型):

  

第一案:

r => (r.Employee as ContractEmployee).Amount > 10000 
     

修正:

r => (r.Employee is ContractEmployee) && r.Amount > 10000
     

第二案:

_context.Remunerations.Where(r => (r.Employee as ContractEmployee).ContractMonth > 10);

我需要创建这个表达式

r => (r.Employee as ContractEmployee).ContractMonth > 10

动态。

假设,我得到这个字符串“Employee.ContractMonth> 10”,我知道我需要在编码时将其转换为ContractEmployee。

我可以将其转换为表达式,如下所示:

PropertyInfo p = typeof(Remuneration).GetProperty("Employee.ContractMonth");
ParameterExpression lhsParam = Expression.Parameter(typeof(Remuneration));
Expression lhs = Expression.Property(lhsParam, p);
Expression rhs = Expression.Constant(Convert.ChangeType("10", pi.PropertyType));
Expression myoperation = Expression.MakeBinary(ExpressionType.GreaterThan, lhs, rhs);

上述代码无效,因为“ContractMonth”不属于“Employee”类。

  

如何使用表达式树将Employee强制转换为ContractEmployee:   r => (r.Employee as ContractEmployee).ContractMonth> 10

由于

1 个答案:

答案 0 :(得分:2)

您正在尝试访问错误对象上的属性。

你有

r => (r.Employee as ContractEmployee).Amount > 10000 

虽然它应该是:

r => (r.Employee is ContractEmployee) && r.Amount > 10000

我要把它留给你来建立这个lambda的表达式

这样的事情:

Expression.And(
            Expression.TypeIs(Expression.Parameter(typeof(Employee), "r"), typeof(ContractEmployee)),
            Expression.GreaterThan(Expression.Property(Expression.Parameter(typeof(Employee), "r"), "Ammount"), Expression.Constant(10000))
        )