0

EF4 프로젝트를 도메인으로 사용하는 MVC3 프로젝트가 있습니다. 도메인은 T4를 사용하여 POCO 개체를 만드는 모델 첫 번째 프로젝트입니다. 도메인에 여러 ComplexType이 있습니다. context.CreateObject()에서 반환 한 프록시를 사용하는 한 모든 것이 훌륭하게 작동합니다.현재 값을 POCO에서 DynamicProxy에 적용하면 복잡한 개체에 오류가 발생합니다.

MVC3 동작이 호출되면 모델 바인더는 도메인에 적용될 변경 사항이 포함 된 프록시가 아닌 개체를 전달합니다.

"proxy'ed"원본을 사용하여 나중에 뷰가 탐색 속성에 액세스 할 수 있도록하고 싶습니다. 따라서 직선적 인 AttachTo가이를 잘라 내지 않습니다.

먼저 "원래"proxy'ed 개체를 컨텍스트에서 가져온 다음 모델 바인더에서 제공 한 POCO에 포함 된 변경 내용으로 업데이트해야합니다.

[InvalidOperationException: The entity of type 'System.Data.Entity.DynamicProxies.Value_E954C24C522BA1D4124F434A57391656EFA4DD7CEFFD3A5CE35FC1532CD1B10A' references the same complex object of type 'Domain.DateRange' more than once. Complex objects cannot be referenced multiple times by the same entity.] 
    System.Data.Objects.EntityEntry.CheckForDuplicateComplexObjects(Object complexObject) +418 
    System.Data.Objects.EntityEntry.DetectChangesInProperties(Boolean detectOnlyComplexProperties) +211 
    System.Data.Objects.Internal.EntityWithChangeTrackerStrategy.UpdateCurrentValueRecord(Object value, EntityEntry entry) +93 
    System.Data.Objects.Internal.EntityWrapper`1.UpdateCurrentValueRecord(Object value, EntityEntry entry) +17 
    System.Data.Objects.EntityEntry.ApplyCurrentValuesInternal(IEntityWrapper wrappedCurrentEntity) +107 
    System.Data.Objects.ObjectContext.ApplyCurrentValues(String entitySetName, TEntity currentEntity) +365 
    : 내 문제는이 오류가

    public static T GetUpdatedProxy<T>(this ObjectContext context, string entitySetName, T entity) 
        where T : class 
    { 
        object original; // db original POCO, proxy wrapped. 
        var entityKey = context.CreateEntityKey(entitySetName, entity); 
    
        //Load DB object 
        context.GetObjectByKey(entityKey, out original) 
        //Apply changes from binder supplied POCO object. 
        context.ApplyCurrentValues<T>(entitySetName, entity); //<= error here 
        return (T) original; 
    } 
    

    :

    내가 읽은, 나의 연구는 나에게 말한다 것과

    , 나는 다음과 같은 사용하여이 일을 수행 할 수 있어야한다

  • 프록시 객체가 아닌 객체의 객체와 객체의 객체는 동일하지 않습니다.
  • 엔터티에는 하나의 복합 개체 만 있으므로 같은 ComplexType의 두 속성을 여러 번 설정할 수 없습니다.
  • 복잡한 개체 자체에는 실제로 값이 설정되어 있지 않으므로 두 개의 null 가능 필드가 실제로 null입니다.
  • AttachTo 메서드를 사용하고 개체 상태를 수정하도록 설정하면 저장이 작동하지만 나중에 탐색 속성이 null이므로 개체를 사용하여보기를 반환 할 수 없습니다.

의견이 있으십니까? 도움에 감사드립니다.

답변

0

나는 결국 해결 방법을 알아 냈습니다. 나는 context.ApplyCurrentValues ​​()를 POCO에서 Proxy로 작업 할 수 없다.

내가 가진 해결책은 IOC CreateObject() 메서드에서 새 프록시를 만들고, 반향을 사용하여 POCO의 속성을 복사 한 다음 프록시로 AttachTo()를 호출하는 것이 었습니다.

public static T GetUpdatedProxy<T>(this ObjectContext context, string entitySetName, T entity) 
    where T : class 
{ 
    var proxy = context.CreateObject<T>(); 

    //Copy ComplexObjects and values over. 
    foreach(var property in typeof(T).GetProperties().Where(p => p.CanWrite && p.CanRead)) 
     if(typeof(IComplexObject).IsAssignableFrom(property.PropertyType)) 
      proxy.SetValueOf(property, (entity.GetValueOf(property) as IComplexObject).Clone()); //<== Clone the ComplexType 
     else if(typeof(System.ValueType).IsAssignableFrom(property.PropertyType) || typeof(System.String).IsAssignableFrom(property.PropertyType)) 
      proxy.SetValueOf(property, entity.GetValueOf(property)); 

    context.AttachTo(entitySetName, proxy); 
    context.ObjectStateManager.ChangeObjectState(entity, EntityState.Modified); 
    entity = (T) proxy; 
} 

나는 반복하고 (으로 getObject 밖으로 entityKey) context.TryGetObjectByKey에서 사전로드 된 프록시 속성을 복사하는 시도했지만 나에게 복잡한 객체 인 널 (null)에 대한 다른 오류를 (어떤이 아니었다) 줄 것이다 상황을 저장할 때.

는 내가 클론 수있는 인터페이스를 추가 그것은 T4 템플릿에 복합 유형에 구현의 :

public static object GetValueOf(this object item, PropertyInfo property) 
{ 
    return property.GetValue(item, null); 
} 

public static object GetValueOf(this object item, string property) 
{ 
    return GetValueOf(item, item.GetType().GetProperty(property)); 
} 

public static void SetValueOf(this object item, PropertyInfo property, object value) 
{ 
    property.SetValue(item, value, null); 
} 

public static void SetValueOf(this object item, string property, object value) 
{ 
    SetValueOf(item, item.GetType().GetProperty(property), value); 
} 
:

public interface IComplexObject : ICloneable {} 
... 
object ICloneable.Clone(){ return this.Clone(); } 
public DateRange Clone(){ return (DateRange) this.MemberwiseClone(); } 

SetValueOf 및 GetValueOf 내가 가독성을 위해 사용하는 간단한 확장 방법이다

관련 문제