2015-01-08 4 views
2

주어진 EntityCollection<T>의 소유자가 컨텍스트에서 분리되었는지 여부를 알아야합니다. 그 이유는 컬렉션에 대한 후속 Load() 호출이 실패하지 않도록하기 위해서입니다. 그러나 컬렉션의 _ owner 및 _ wrappedOwner 필드는 액세스 할 수 없으며 사용 가능한 메타 데이터 중 아무 것도이 정보를 제공하지 않는 것 같습니다.EntityCollection <T>이 주어지면 소유자인지 여부를 확인하는 방법은 무엇입니까?

소유자 (또는 적어도 EntityState)를 찾는 방법이 있습니까?

컨텍스트 : 우리가 허용되지 않기 때문에이 정책에 의해, 지연로드를 사용하는, 내가 바람직 일반적인 방법을 사용하여 필요할 때 몇 가지 쉬운 명시 적으로 늦게 로딩을 만들려고합니다.

public static EntityCollection<T> ReloadIfNeeded<T>(this EntityCollection<T> collection, EntityObject owner) where T : EntityObject { 
    if (owner.EntityState != EntityState.Detached && !collection.IsLoaded) { 
     collection.Load(); 
    } 
    return collection; 
} 

예 전화 : 내가 .NET 버전 4.0을 사용하고

var orders = customer.Orders.ReloadIfNeeded(customer); //I would like to get rid of the customer parameter here... 

이것은 내가 매개 변수로 주인을 요청, 현재 그것을 할 방법이다.

편집 : 내 솔루션, Ognyan 디미트로프로 대답 구현 : 원래 잘 나가로이 엔티티의 상태를 고려하지 않습니다

public static EntityCollection<T> ReloadIfNeeded<T>(this EntityCollection<T> collection) where T : EntityObject { 
    try { 
     if (!collection.IsLoaded) { 
      collection.Load(); 
     } 
    } catch (InvalidOperationException) { 
     //just leave unloaded 
    } 
    return collection; 
} 

을하지만, 시도의 비용에 원치 않는 매개 변수를 제거한다/catch 절.

internal void Load(List<IEntityWrapper> collection, MergeOption mergeOption) 
{ 
    bool flag; 
    ObjectQuery<TEntity> query = base.ValidateLoad<TEntity>(mergeOption, "EntityCollection", out flag); 
    base._suppressEvents = true; 
    try 
    { 
     if (collection == null) 
     { 
      base.Merge<TEntity>(flag ? RelatedEnd.GetResults<TEntity>(query) : Enumerable.Empty<TEntity>(), mergeOption, true); 
     } 
     else 
     { 
      base.Merge<TEntity>(collection, mergeOption, true); 
     } 
    } 
    finally 
    { 
     base._suppressEvents = false; 
    } 
    this.OnAssociationChanged(CollectionChangeAction.Refresh, null); 
} 

그것은 그 다음과 같습니다

+0

해당 필드가 비공개입니까? 그렇다면 반성을 사용하여 얻을 수 있습니다. –

+0

@OgnyanDimitrov 예, 알고 있습니다. 그러나 나는 이것이 정말로 느려질 것이라고 생각한다. – Marcel

+0

대부분의 경우 실제 성능은 CPU 시간이 아니라 IO 디스크 읽기/쓰기, db 쿼리, 외부 서비스 등에서 발생합니다. 또한이를 측정 할 수도 있습니다. 결국 그것은 최종 사용자가 프로그램을 어떻게 느끼는지/인식하는지에 관한 것입니다. EF에 대해 2 차 수준 캐시를 구현하려고합니까? –

답변

2

나는이 클래스는 다음 다른 내부 Load 메서드를 호출

public override void Load(MergeOption mergeOption) 
{ 
    base.CheckOwnerNull(); 
    this.Load(null, mergeOption); 
} 

공개 방법을 가지고 볼 수 리플렉터와 EntityCollection을 빗질하고 코드보고 소유자가 있으면 내부적으로 검사하여 예외를 잡는 경우 '후속 Load() 실패'를 방지합니다. MergeOption을 사용하여 Load (MergeOption)를 호출하면 언제든지 지정할 수 있습니다.

케이스에서 '분리됨'은 엔티티가 POST 요청에서 프런트 엔드에서 방금 온 것을 의미합니까? 부모 엔티티를 분리하는 것은 같은 상태로 아이들의 '상태'설정에 반영 할 경우 나도 몰라

_context.Entry(entity).State 

: 상위 기업에 이전 액세스 할 수있는 경우 당신은 그것의 상태를 확인할 수 있습니다.

+0

필자의 경우 "분리됨"은 대부분 객체가 메모리에 생성되어 컨텍스트에 추가되지 않았 음을 의미합니다. – Marcel

+0

관련 코드 주위에 try/catch를 추가하여 솔루션 제안대로 대부분 수행했습니다. – Marcel