未定义成员表达式属性
本文关键字:属性 表达式 成员 未定义 | 更新日期: 2023-09-27 18:32:12
我需要帮助。我有两个类:实体和模型。他们的代码如下。
public class TestEntityForSerialize
{
public String FIO { get; set; }
public DateTime Birthday { get; set; }
public String Name { get; set; }
}
[DataContract]
public class TestModelForSerialize
{
[DataMember]
public String FIO { get; set; }
[DataMember]
public DateTime Birthday { get; set; }
[DataMember(Name = "Name")]
public String BigName { get; set; }
public Int32 Age { get; set; }
}
主要任务是以编程方式将任何Func<TestModelForSerialize, Boolean>
转换为Func <TestEntityForSerialize, Boolean>
。我的决定是使用表达式树。我正在使用 ExpressionVisitor 来迭代模型的表达式树的节点,并使用实体作为参数构造一个新的表达式。这些 Func 的通用参数在类中设置,保存功能。
我已经通过覆盖VisitParameter方法成功地转换了ParameterExpression,但是我卡住了覆盖ExpressionVisitor后代的VisitMember方法。 事实上,我有代码:访问成员覆盖:
protected override Expression VisitMember(MemberExpression node)
{
Expression e = base.VisitMember(node);
MemberExpression me = e as MemberExpression;
if (me != null)
{
String modelPropertyName = ((PropertyInfo)me.Member).Name;
ParameterExpression pe = node.Expression as ParameterExpression;
TModel m = Activator.CreateInstance<TModel>();
PropertyInfo memberPI = GetEntityProperty(m, modelPropertyName);
MemberExpression meToReturn = Expression.Property(Expression.Parameter(typeof(TEntity)), memberPI);
return meToReturn;
}
else
{
return base.VisitMember(node);
}
}
访问参数覆盖:
protected override Expression VisitParameter(ParameterExpression node)
{
ParameterExpression pe = base.VisitParameter(node) as ParameterExpression;
if (pe.Type == typeof(TModel))
{
ParameterExpression ex = Expression.Parameter(typeof(TEntity), pe.Name);
return ex;
}
else
{
return pe;
}
}
GetEntityProperty 是 TModel 类到 TEntity 类属性的方法映射属性。它使用 DataContract 和 DataMember 进行映射。
protected PropertyInfo GetEntityProperty(TModel model, String propertyName)
{
PropertyInfo property = model.GetType().GetProperty(propertyName);
if (property != null)
{
Attribute attr = property.GetCustomAttribute(typeof(DataMemberAttribute));
if (attr != null)
{
String entityPropertyName = (((DataMemberAttribute)attr).Name != null ? ((DataMemberAttribute)attr).Name : propertyName);
return typeof(TEntity).GetProperty(entityPropertyName);
}
else
{
throw new DataMemberAttributeNotFoundException();
}
}
else
{
throw new MissingMemberException();
}
}
测试方法是
[TestMethod]
public void TestVisitMemberShouldReplaceModelWithEntity()
{
ParameterExpression p = Expression.Parameter(typeof(TestModelForSerialize));
Type tm = typeof(TestModelForSerialize);
PropertyInfo birthdayProp = tm.GetProperty("FIO");
Assert.IsNotNull(birthdayProp);
MemberExpression me = Expression.Property(p, birthdayProp);
VisitorForTests vft = new VisitorForTests();
MemberExpression meResult = vft.VisitMemberForTest(me) as MemberExpression;
Assert.IsInstanceOfType(meResult.Member, typeof(PropertyInfo));
}
VisitorForTests是在类中调用受保护方法的类,我正在尝试处理。它的方法:
public Expression VisitMemberForTest(MemberExpression node)
{
return this.VisitMember(node);
}
当我尝试调用 VisitMember 方法时,它会压在第一行("表达式 e = base。VisitMember(node);"),抛出带有消息的 ArgumentException:属性"FIO"未在类 "TestEntityForSerialize" 中定义。我唯一能注意到的 - 访问会员尝试启动访问参数方法,并在得到它的结果后 - 粉碎。
任何帮助都非常感谢。
明白了!正如俄罗斯谚语所说:"沉没的人拯救 - 这个人的手是自己的事。问题是 - 我试图使用带有错误参数的表达式。它应该提供 TEntity 的属性,我会提供它 TModel 的属性。所以只需轻轻改变访问会员方法和卡瓦班加!
protected override Expression VisitMember(MemberExpression node)
{
//Expression e = base.VisitMember(node); - I've commented this line
MemberExpression me = node as MemberExpression;
if (me != null)
{
String modelPropertyName = ((PropertyInfo)me.Member).Name;
ParameterExpression pe = node.Expression as ParameterExpression;
TModel m = Activator.CreateInstance<TModel>();
PropertyInfo memberPI = GetEntityProperty(m, modelPropertyName);
MemberExpression meToReturn = Expression.Property(Expression.Parameter(typeof(TEntity)), memberPI.Name);
return base.VisitMember(meToReturn); //and changed this line
}
else
{
return base.VisitMember(node);
}
}
这行得通!