programing

개체가 Entity Framework의 데이터 컨텍스트에 이미 연결되어 있는지 확인할 수 있습니까?

nasanasas 2020. 9. 25. 07:56
반응형

개체가 Entity Framework의 데이터 컨텍스트에 이미 연결되어 있는지 확인할 수 있습니까?


다음을 통해 주어진 컨텍스트에 이미 연결된 개체를 연결하려고 할 때 다음 오류가 발생합니다 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;
}

Given the situation that you describe in your edit, you might need to use the following overload that accepts an EntityKey instead of an object:

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

To build an EntityKey in your situation, use the following as a guideline:

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

You can get the EntityKey from an existing instance of User by using the property User.EntityKey (from interface IEntityWithKey).


Using the entity key of the object you are trying to check:

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

Kindness,

Dan


This does not directly answer OPs question but this is how I solved mine.

This is for those who are using DbContext instead of ObjectContext.

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

DbSet.Find Method:

Finds an entity with the given primary key values. If an entity with the given primary key values exists in the context, then it is returned immediately without making a request to the store. Otherwise, a request is made to the store for an entity with the given primary key values and this entity, if found, is attached to the context and returned. If no entity is found in the context or the store, then null is returned.

Basically, it returns the attached object of the given primaryKey so you just need to apply the changes on the returned object to keep the right instance.

참고URL : https://stackoverflow.com/questions/1715501/is-is-possible-to-check-if-an-object-is-already-attached-to-a-data-context-in-en

반응형