2014-01-30 4 views
2

표현식을 사용하여 매핑 설정을 정의하는 데 사용되는 SetMapping() 메서드가 있습니다.일반 표현 추상화 문제

public class AggregateMap<TDataEntity> 
{ 
    protected Expression<Func<IUpdateConfiguration<TDataEntity>, object>> graphMapping; 

    protected void SetMapping(Expression<Func<IUpdateConfiguration<TDataEntity>, object>> mapping) 
    { 
     graphMapping = mapping; 
    } 
} 

예 호출 코드 :

SetMapping(map => map.OwnedCollection(root => root.ChildEntities)); 

는 위의 잘 작동,하지만 난 SetOwnedCollectionMapping()를 제공함으로써 조금 더 추상적이 방법 싶습니다. 이것은 호출 코드가 훨씬 더 기본적인 표현을 제공 할 수 있음을 의미합니다.

또한 추상화 방법

protected void SetOwnedCollectionMapping<T>(Expression<Func<TDataEntity, ICollection<T>>> mapping) 
{ 
    graphMapping = map => map.OwnedCollection<TDataEntity, T>(mapping); 
} 

예 전화 번호 :

graphMapping 필드는 다음 엔티티 프레임 워크에서 다음 메소드를 호출하여 외부 라이브러리 (RefactorThis.GraphDiff)에서 사용된다
SetOwnedCollectionMapping(root => root.ChildEntities); 

DbContext 인스턴스 :

public static void UpdateGraph<T>(this DbContext context, T entity, Expression<Func<IUpdateConfiguration<T>, object>> mapping) where T : class; 

다음과 같은 예외가 실행시에 발생되는 :

'System.InvalidCastException가' RefactorThis.GraphDiff.dll에서 발생했지만 사용자 코드에서

추가 정보 처리되지 않은 유형의 예외 : 캐스팅 할 수 없습니다를 형식이 인 'System.Reflection.RtFieldInfo'의 개체에 'System.Reflection.PropertyInfo'를 입력합니다.

필자의 제네릭 유형을 혼란스럽게해야하지만 이전 구현과 새로운 구현 간의 차이점을 볼 수 없습니다.

public static IUpdateConfiguration<T> OwnedCollection<T, T2>(this IUpdateConfiguration<T> config, Expression<Func<T, System.Collections.Generic.ICollection<T2>>> expression); 

편집 : 추가 UpdateGraph 정보는 의문을 제기하는 여기

OwnedCollection 방법 서명입니다.

+0

Reflection이 들어오는 곳이 누락되었습니다. 뭔가를 감독합니까? –

+0

@PatrickHofman : 질문을 개정했습니다. 미안합니다. – davenewza

+0

와우. 편집 내역은 답변 내에 있습니다. – davenewza

답변

2

두 구현의 주요 차이점은 두 번째 구현에서는 메소드 매개 변수를 캡처하지만 첫 번째 구현에서는 메소드 매개 변수를 캡처하지 않는다는 점입니다. 매개 변수는 클로저의 필드로 저장되며 해당 필드 액세스가있을 경우 RefactorThis.GraphDiff.dll에 문제가 발생할 가능성이 있습니다. 다음으로 두 번째 구현 변화

시도는 :

protected void SetOwnedCollectionMapping<T>(Expression<Func<TDataEntity, ICollection<T>>> mapping) 
{ 
    // 
    // Hack to resolve the `OwnedCollection` extension method. 
    // 
    Expression<Func<IUpdateConfiguration<TDataEntity>, object>> template = 
     _ => _.OwnedCollection(mapping); 

    var map = Expression.Parameter(
     typeof(IUpdateConfiguration<TDataEntity>), 
     "map"); 

    graphMapping = Expression.Lambda<Func<IUpdateConfiguration<TDataEntity>, object>>(
     Expression.Call(
      ((MethodCallExpression)template.Body).Method, 
      map, 
      Expression.Quote(mapping)), 
     map); 
} 

graphMapping의 값은 첫 번째 구현에 의해 제조 된 것과 동일 할 것이다.