Мне нужна помощь. У меня есть два класса: сущность и модель. Их код ниже.Свойство MemberExpression не определено
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 для итерации узлов дерева выражений модели и для создания нового параметра Expression with Entity в качестве параметра. Общие параметры этих Func устанавливаются в классе, поддерживая функциональность.
Я преуспел в преобразовании ParameterExpression, переопределив метод VisitParameter, но я застрял с переопределением метода VisitMember для потомка 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);
}
}
VisitParameter переопределение:
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();
}
}
The TestMethod является
[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, он давит на первой линии («Выражение е = base.VisitMember (узел);»), метание ArgumentException с сообщением: Property «FIO» является не определен в классе «TestEntityForSerialize». Единственное, что я мог заметить - VisitMember пытается запустить метод VisitParameter, а после получения его результата - раздавит.
Любая помощь очень ценится.
Не могли бы вы включить полный код, демонстрирующий проблему? В частности: как реализуется «GetEntityProperty()»? Откуда берутся общие параметры? – svick
Спасибо за ответ. GetEntityProperty() - метод, вычисляющий отображение свойства Entity в свойство Model. Он был протестирован и работал правильно. Общие параметры, заданные в классе, который содержит метод. Я постараюсь продлить эту должность. –