다음을 통해 주어진 컨텍스트에 이미 연결된 개체를 연결하려고 할 때 다음 오류가 발생합니다 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에서 ).User
User.EntityKey
IEntityWithKey
답변
확인하려는 개체의 엔터티 키 사용 :
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
변경 사항을 적용하여 올바른 인스턴스를 유지하기 만하면됩니다.