개체가 Entity Framework의 데이터 컨텍스트에 이미 연결되어 있는지 확인할 수 있습니까? 달성하는 방법이 있습니까? context.IsAttachedTo(…) 건배! 편집하다: Jason이

다음을 통해 주어진 컨텍스트에 이미 연결된 개체를 연결하려고 할 때 다음 오류가 발생합니다 context.AttachTo(...).

동일한 키를 가진 개체가 ObjectStateManager에 이미 있습니다. ObjectStateManager는 동일한 키를 가진 여러 개체를 추적 할 수 없습니다.

다음을 따라 무언가를 달성하는 방법이 있습니까?

context.IsAttachedTo(...)

건배!

편집하다:

Jason이 설명한 확장 방법은 비슷하지만 내 상황에서는 작동하지 않습니다.

다른 질문에 대한 답변에 설명 된 방법을 사용하여 몇 가지 작업을 수행하려고합니다.

행을 먼저 검색하지 * 않고 * Linq to Entities를 사용하여 테이블에서 하나 이상의 행을 삭제하려면 어떻게해야합니까?

내 코드는 다음과 같습니다.

var user = new User() { Id = 1 };
context.AttachTo("Users", user);
comment.User = user;
context.SaveChanges();

동일한 방법을 사용하고 더미 User개체 를 첨부하려고하는 사용자를 위해 다른 작업을 수행하는 경우를 제외하고는 정상적으로 작동 합니다. 이전에 해당 더미 사용자 개체를 연결했기 때문에 실패합니다. 이것을 어떻게 확인할 수 있습니까?



답변

다음은 매우 훌륭하게 작동하는 결과입니다.

public static void AttachToOrGet<T>(this ObjectContext context, string entitySetName, ref T entity)
    where T : IEntityWithKey
{
    ObjectStateEntry entry;
    // Track whether we need to perform an attach
    bool attach = false;
    if (
        context.ObjectStateManager.TryGetObjectStateEntry
            (
                context.CreateEntityKey(entitySetName, entity),
                out entry
            )
        )
    {
        // Re-attach if necessary
        attach = entry.State == EntityState.Detached;
        // Get the discovered entity to the ref
        entity = (T)entry.Entity;
    }
    else
    {
        // Attach for the first time
        attach = true;
    }
    if (attach)
        context.AttachTo(entitySetName, entity);
}

다음과 같이 호출 할 수 있습니다.

User user = new User() { Id = 1 };
II.AttachToOrGet<Users>("Users", ref user);

context.AttachTo(...)매번 위에서 인용 한 ID 트릭을 사용할 수 있다는 점을 제외하면 매우 훌륭하게 작동합니다 . 이전에 부착 된 객체 또는 부착 된 자신의 객체로 끝납니다. CreateEntityKey컨텍스트를 호출 하면 멋지고 일반적이며 더 이상 코딩하지 않고도 복합 키로도 작동합니다 (EF가 이미이를 수행 할 수 있기 때문입니다!).


답변

더 간단한 방법은 다음과 같습니다.

 bool isDetached = context.Entry(user).State == EntityState.Detached;
 if (isDetached)
     context.Users.Attach(user);


답변

이 확장 방법을 시도해보십시오 (테스트되지 않았으며 즉시 사용 가능).

public static bool IsAttachedTo(this ObjectContext context, object entity) {
    if(entity == null) {
        throw new ArgumentNullException("entity");
    }
    ObjectStateEntry entry;
    if(context.ObjectStateManager.TryGetObjectStateEntry(entity, out entry)) {
        return (entry.State != EntityState.Detached);
    }
    return false;
}

편집에서 설명하는 상황을 감안할 때 EntityKey객체 대신를 허용하는 다음 오버로드를 사용해야 할 수 있습니다 .

public static bool IsAttachedTo(this ObjectContext, EntityKey key) {
    if(key == null) {
        throw new ArgumentNullException("key");
    }
    ObjectStateEntry entry;
    if(context.ObjectStateManager.TryGetObjectStateEntry(key, out entry)) {
        return (entry.State != EntityState.Detached);
    }
    return false;
}

EntityKey상황에 맞게 구축하려면 다음을 지침으로 사용하십시오.

EntityKey key = new EntityKey("MyEntities.User", "Id", 1);

속성을 사용하여의 EntityKey기존 인스턴스에서을 가져올 수 있습니다 (interface에서 ).UserUser.EntityKeyIEntityWithKey


답변

확인하려는 개체의 엔터티 키 사용 :

var entry = context.ObjectStateManager.GetObjectStateEntry("EntityKey");
if (entry.State == EntityState.Detached)
{
  // Do Something
}

친절,


답변

이것은 OPs 질문에 직접 대답하지는 않지만 이것이 내가 어떻게 해결했는지입니다.

DbContext대신을 사용 하는 사람들을위한 것입니다 ObjectContext.

    public TEntity Retrieve(object primaryKey)
    {
        return DbSet.Find(primaryKey);
    }

DbSet.Find 메서드 :

주어진 기본 키 값이있는 항목을 찾습니다. 주어진 기본 키 값을 가진 엔터티가 컨텍스트에 있으면 저장소에 요청하지 않고 즉시 반환됩니다. 그렇지 않으면 주어진 기본 키 값을 가진 엔티티에 대한 요청이 저장소에 작성되고이 엔티티가 발견되면 컨텍스트에 첨부되고 리턴됩니다. 컨텍스트 또는 저장소에 엔티티가 없으면 null이 반환됩니다.

기본적으로 주어진의 첨부 된 객체를 반환하므로 반환 된 객체에 primaryKey변경 사항을 적용하여 올바른 인스턴스를 유지하기 만하면됩니다.


답변