我有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。这不是正确的方式。
答案 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";