通过表达式获取/设置属性

时间:2014-06-30 11:40:49

标签: c# lambda

尝试通过将oracle数据库中的字段映射到对象的属性来创建数据访问组件。我已经创建了一个带有类型的基础对象,并且像这样被调用...

public class Document : DataProviderBase<DataObjects.Document> 
{ 
    // code goes here... 
}

这个基础对象有一个名为AddMapping的方法,它将数据库字段映射到这样的属性......

this.AddMapping<int>("ATD_KEY", "Key")

在这种情况下......

  • int 是属性类型
  • ATD_KEY 是数据库中的字段名称
  • Key DataObjects.Document
  • 上的媒体资源名称

代码使用......

typeof(<TParent>).GetProperty(<property name>)

..获取用于获取和设置属性的PropertyInfo。 虽然这很棒,但我想在AddMapping方法中添加一些类型为safety和lambda的表达式。我想做以下的事......

this.AddMapping<int>("ATD_KEY", o => o.Key)

..其中o属于DataProviderBase提供的类型。这将确保属性Key实际上是int类型,并确保字符串"Key"不是拼写错误或错误的情况,因为第一个{{1}中显示的当前工作代码存在问题{1}}方法。

这可能吗?如果是这样的话?

我发现的最接近的例子就是这个 Dynamic Expression from the Property of the object of the class,但这仍然是按字符串而不是表达式引用属性。

2 个答案:

答案 0 :(得分:1)

您可以使用以下内容:

public void AddMapping<T>(fieldName, Expression<Func<TParent, T>> propExpr)
{
    var memberExpr = (MemberExpression)propExpr.Body;
    PropertyInfo property = (PropertyInfo)memberExpr.Member;
    ...
}

答案 1 :(得分:1)

当然可以:

public static PropertyInfo GetProperty<TParent>(Expression<Func<TParent, object>> prop)
{
    var expr = prop.Body;

    if (expr.NodeType == ExpressionType.Convert)
        expr = ((UnaryExpression)expr).Operand;

    if (expr.NodeType == ExpressionType.MemberAccess)
        return ((MemberExpression)expr).Member as PropertyInfo;

    throw new ArgumentException("Invalid lambda", "prop");
}

public void AddMapping<TParent>(fieldName, Expression<Func<TParent, object>> prop)
{
    AddMapping(fieldName, GetProperty(prop).Name);
}

此方法的优点是只需要一个类型参数(TParent)。您将可能包含强制转换的lambda传入属性类型。我们摆脱它,然后得到成员表达。