通过表达式获取/设置属性
本文关键字:设置 属性 获取 表达式 | 更新日期: 2023-09-27 18:10:59
尝试通过将字段从 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
方法中显示的当前工作代码存在问题一样。
这可能吗?如果是,如何?
我发现的最接近的例子是这个来自类对象的属性的动态表达式,但这仍然按字符串而不是表达式引用属性。
你可以使用如下的东西:
public void AddMapping<T>(fieldName, Expression<Func<TParent, T>> propExpr)
{
var memberExpr = (MemberExpression)propExpr.Body;
PropertyInfo property = (PropertyInfo)memberExpr.Member;
...
}
当然有可能:
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,该 lambda 可能包含对属性类型的强制转换。我们摆脱它,然后得到成员表达式。