2

我完全迷失了这个。我有一段代码在这样实现时可以满足我的需要:

return filters.Add(m => m.Metadata.RecordId).IsEqualTo(1);

其中 m 是TestObj类对象,Add方法的参数是Expression<Func<TestObj,bool?>>

现在的问题是我不能在 Add 中硬编码 m.Metadata.RecordId,因为我在这里得到的是一个字符串,它告诉我应该使用的属性,在本例中是“Metadata.RecordId”。我需要做的是用这个字符串构造这样一个表达式,它的作用与 m => m.Metadata.RecordId 一样。我需要这样的东西:

string propertyName = "Metadata.RecordId";
Expression expr = null;//create expression here somehow that will do the same as m => m.Metadata.RecordId
return filters.Add(expr).IsEqualTo(1); 

我怎么做?

4

2 回答 2

1

我不确定你到底想要什么作为输出(bool、int 和比较),
但这应该让你走上正确的轨道......

public static void Test(string propertyPath)
{
    var props = propertyPath.Split('.');
    Expression parameter = Expression.Parameter(typeof(TestObj), "x");
    Expression property = parameter;
    foreach (var propertyName in props)
        property = Expression.Property(property, propertyName);
    Expression<Func<TestObj, int>> lambdaExpression =
        Expression.Lambda<Func<TestObj, int>>(property, parameter as ParameterExpression);
    Add(lambdaExpression);
}
static void Add(Expression<Func<TestObj, int>> paramExp)
{
    TestObj obj = new TestObj { Metadata = new Metadata { RecordId = 1, Name = "test" } };
    var id = paramExp.Compile()(obj);
}

您还可以查看 Jon 的这篇文章,它很好地描述了它是如何工作的……
使用反射从属性 Name 中获取 lambda 表达式

于 2013-04-12T15:28:18.507 回答
0

这个电话怎么样:

return filters.Add(m => ReflectionMagic(m, "Metadata.RecordId").IsEqualTo(1);

该方法将具有以下签名:

public object ReflectionMagic(object source, string property);

如果这样可行,您可以执行以下操作:

var propertyTree = property.Split('.');

foreach(var propertyName in propertyTree)
{
     var propInfo = source.GetType().GetProperty(propertyName);
     var source = propInfo.GetValue(source, null);
}

return source;

请注意,缺少任何类型的参数和返回值检查,并留给读者作为练习。

于 2013-04-12T14:10:39.467 回答