2014-11-26 7 views
2

도움이 필요합니다. 두 클래스가 있습니다 : 엔티티와 모델. 그들의 코드는 아래와 같습니다.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를 사용하고 있습니다. 이러한 Func의 일반 매개 변수는 기능을 보유한 클래스에서 설정됩니다.

VisitParameter 메서드를 재정 의하여 ParameterExpression을 변환하는 데 성공했지만 ExpressionVisitor의 하위 항목 인 VisitMember 메서드를 재정의하는 데 주저했습니다. 사실 나는 코드가 있습니다 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이 TEntity 클래스의 프로퍼티의 tModel 클래스의 메소드 매핑 속성입니다. 그것은 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

[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 클래스에서 보호 된 메소드를 호출 할 수있는 클래스입니다, 내가 처리하기 위해 노력하고있어. 속성 'FIO "입니다 :;, 메시지와 함께 ArgumentException이 던지는 내가 VisitMember 메소드를 호출 할 때, 그것은 첫 번째 줄에 분쇄

public Expression VisitMemberForTest(MemberExpression node) 
    { 
     return this.VisitMember(node); 
    } 

("식 e는 = base.VisitMember (노드) ") : 그것은 방법입니다 "TestEntityForSerialize"클래스에는 정의되어 있지 않습니다. 내가 알아 차릴 수있는 것 - VisitMember는 VisitParameter 메소드를 시작하려고 시도하고, 결과를 얻은 후에 - 반하게합니다.

도움이 매우 감사합니다.

+0

문제를 나타내는 전체 코드를 포함 할 수 있습니까? 구체적으로 :'GetEntityProperty()'는 어떻게 구현됩니까? 일반적인 매개 변수는 어디서 오는가? – svick

+0

답변 해 주셔서 감사합니다. GetEntityProperty() - Model 속성에 매핑되는 Entity 속성을 계산하는 메서드입니다. 그것은 테스트를 거쳤으며 올바르게 작동합니다. 메소드를 포함하는 클래스에 일반 매개 변수가 설정되었습니다. 나는 그 지위를 새롭게하려고 노력할 것이다. –

답변

1

Gotcha! 러시아 속담에 "저축하는 사람을 구하는 것 -이 사람의 손은 자신의 사업입니다." 문제는 - 잘못된 매개 변수로 Expression을 사용하려고했습니다. 그것은 TEntity의 속성으로 제공되어야하며 TModel의 속성을 제공해야합니다. 그래서 가볍게 VisitMember 방법과 Qawabanga의 변화!

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); 
     } 
    } 

그리고이 작품!

관련 문제