如何在c#表达式中调用属性中的属性?

时间:2014-07-01 12:01:56

标签: c# expression

我有3节课。

    AutoYearMake{
       int Year { get; set; }
       string Make { get; set; }
            }

    AutoModel{
       IAutoYearMake AutoYearMakeParent { get; set; }
       string Model { get; set; }
            } 

    AutoTrim{
        IAutoModel AutoModelParent { get; set; }
        string Trim { get; set; }
            }

我需要为数据库创建一个查询。如何动态获得如下表达式:

   Expression<Func<AutoTrim, bool>> expression =  expression = t => t.AutoModelParent.AutoYearMakeParent.Year == year.Value
                              && t.AutoModelParent.AutoYearMakeParent.Make 
                              == make && t.AutoModelParent.Model == model; 

这是我的代码。它没有用。

        ParameterExpression parameter = Expression.Parameter(typeof (AutoTrim), "a");

        MemberExpression yearProp = Expression.Property(parameter, "AutoModelParent.AutoYearMakeParent.Year");
        MemberExpression makeProp= Expression.Property(parameter, "AutoModelParent.AutoYearMakeParent.Make");
        MemberExpression modelProp= Expression.Property(parameter, "AutoModelParent.Model");

        Expression right = Expression.Constant(2014);
        Expression e1 = Expression.Equal(yearProp, right);
        right = Expression.Constant("make");
        Expression e2 = Expression.Equal(makeProp, right);
        right = Expression.Constant("model");
        Expression e3 = Expression.Equal(modelProp, right);

        Expression predicateBody = Expression.AndAlso(e1, e2);
        Expression final = Expression.AndAlso(e1, e2); 

如何解决此问题?我试着使用Expression.Call。这不是正确的方式。

3 个答案:

答案 0 :(得分:2)

Expression.Property()方法的第一个参数是应该从中访问属性的对象。如果您想从参数AutoModelParent访问属性t,请使用:

Expression.Property(parameter, "AutoModelParent")

因此,如果要访问参数t的AutoModelParent属性的Model属性,可以使用:

Expression.Property(Expression.Property(parameter, "AutoModelParent"), "Model")

答案 1 :(得分:0)

考虑这个解决方案:

private static MemberExpression GetPropertyPathAccessor(Expression parameter, string path)
{
    return (MemberExpression) path.Split('.').Aggregate(parameter, Expression.Property);
}

或者如果你不喜欢单行

private static MemberExpression GetPropertyPathAccessor(Expression parameter, string path)
{
    Expression current = parameter;
    foreach (var propertyName in path.Split('.'))
    {
        current = Expression.Property(current, propertyName);
    }
    return (MemberExpression)current;
}

然后你可以使用:

MemberExpression yearProp = GetPropertyPathAccessor(parameter, "AutoModelParent.AutoYearMakeParent.Year");

答案 2 :(得分:0)

这个怎么样?

之后你有了Func&lt;&gt;在expFunc中,您可以立即使用它。

var argParam = Expression.Parameter(typeof(AutoTrim), "s");
var expFunc = Expression.Lambda<Func<AutoTrim, bool>>(
        Expression.AndAlso(
            Expression.AndAlso(
                Expression.Equal(
                    Expression.Property(Expression.Property(Expression.Property(argParam, "AutoModelParent"), "AutoYearMakeParent"), "Year"), 
                    Expression.Constant(year.Value)),
                Expression.Equal(
                    Expression.Property(Expression.Property(Expression.Property(argParam, "AutoModelParent"), "AutoYearMakeParent"), "Make"),
                    Expression.Constant(make))
            ),
            Expression.Equal(
                Expression.Property(Expression.Property(argParam, "AutoModelParent"), "Model"), 
                Expression.Constant(model))
        ),
        argParam
    ).Compile();

但当然你也需要这些(只是示例值):

int? year = 2000;
string make = "BMW";
string model = "6";