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

4

尝试通过将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 方法中增加一些类型安全性和 lambda 表达式。我想做如下操作...

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

...其中o的类型由DataProviderBase提供。这将确保属性Key实际上是int类型,并确保字符串"Key"没有拼错或大小写错误,这是当前工作代码中第一个AddMapping方法存在的问题。

这是否可能?如果可以,如何实现?

我找到的最接近的示例是Dynamic Expression from the Property of the object of the class,但是它仍然通过字符串而不是表达式引用属性。


你想要实现什么还不太清楚:能否请您澄清一下您的问题以及期望解决方案的任何实际优点?谢谢和问候。 - Alexander Bell
这里的目标是类型安全。在之前的方法中,属性名称经常拼写错误并导致错误。这有帮助吗? - Thundter
2个回答

1
你可以使用类似以下的内容:

你可以这样使用:

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

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表达式。我们会去掉它,然后得到成员表达式。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接