2011-08-03 1 views
2

저는 오랜 시간 독자 - 첫 번째 포스터입니다 - 그리고이 Entity Framework 문제에 대한 수많은 연구 끝에 필자는 도움이 필요하다고 느꼈습니다. 저는 C#과 프로그래밍에 익숙하지 않으므로 제발 참아주십시오.개체를 엔터티 집합에 추가하면 불필요한 새 DB 행 (다 대다)이 생성됩니다. 기존 객체와 관계를 생성 하시겠습니까?

웹 2.0 스타일 "태그"를 사용하는 데이터 모델에는 상당히 단순한 다 대다 관계가 있습니다. 이동 태그에는 태그가 있고 사용자에게는 태그가 있습니다.

캐시에서 시프트를 당깁니다. Shift 키를 누른 상태에서 캐시 된 사본의 시프트 세부 정보와 태그를 복사하면 다음과 같은 작업이 수행됩니다 (단순화 된 작업). 내가 명시 적으로() 새로운 태그가 단지 이미 존재하는 태그에 관계를 만드는 대신의 DB에 삽입 SaveChanges를에, 새로운 Data.Tag 객체의 TagID를 설정하더라도

Data.Shift s = new Data.Shift(); 

/* copy over a bunch of stuff from the cached shift object. I'll spare the boring details */  

foreach (var t in shift.Tags) { //shift object is a cached object 

       Data.Tag dt = new Data.Tag 
       { 
        TagID = t.TagID, 
        Name = t.Name, 
        OrgID = t.OrgID, 
       }; 
       s.Tags.Add(dt); 
      } 

DB. TagID 내가 다음 코드를 시도 할 때 PK의 ID 열

입니다 : 쉬프트가 현재 요청 '컨텍스트가 아닌 다른 개체 컨텍스트에서 캐시 때문에 그것은 분명히 실패

foreach (var t in shift.Tags){ 
    s.Tags.Add(t) 
} 

.

의견이 있으십니까? 내가 말할 수있는 한 :

  • 캐시를 지우는 것은 성능 문제로 인해 나를위한 옵션이 아닙니다. 동일한 개체 컨텍스트 내에서이 작업을 수행하면이 모든 문제가 사라질 것입니다.
  • 또한 현재 컨텍스트의 DB에서 Data.Tag를 가져 오는 것은 성능 문제로 인해 옵션이 아닙니다.

이 내가 할 노력하고 있어요 정말 쉬운 일처럼 보인다 ...

편집 좋아 - 난 두 솔루션을 내 코드를 업데이트하려고했지만 둘 다에 문제로 실행하고 있습니다 . 이제 첫 번째 해보자 :

// ctx is grabbed up here from HttpContext.Current.Items 

Data.Shift s = new Data.Shift(); 

/* copy over a bunch of stuff from the cached shift object. I'll spare the boring details */  

foreach (var t in shift.Tags) { //shift object is a cached object 

      Data.Tag dt = new Data.Tag 
      { 
       TagID = t.TagID, 
       Name = t.Name, 
       OrgID = t.OrgID, 
      }; 
      ObjectStateEntry entry; 
      ctx.ObjectStateManager.TryGetObjectStateEntry(t.EntityKey, out entry); 
      if (entry == null || entry.State == EntityState.Detached) { 
        ctx.Tags.Attach(t); 
      } 
      s.Tags.Add(dt); 
     } 

이 다음과 같은 오류 던지고있다 : 시프트 개체와 해당 태그가 당겨 때문에

An entity object cannot be referenced by multiple instances of IEntityChangeTracker. 

내가 무엇입니까 이유는이 오류라고 추측하고있다가,이다 캐시에서 (분명히 다른 컨텍스트에서). 생각?

+0

는 당신이 SaveChanges' '에 대한 전체 코드를 게재 할 수 있습니까? 컨텍스트에 Shift를 어디에 추가합니까? 컨텍스트에 명시 적으로 새 태그를 추가하거나 연결합니까? 문맥에 태그를 붙이는 것은 새로운 태그가 생성되었다는 것을 설명 할 수 없지만 그냥 추측 할 수 있습니다 ... – Slauma

답변

1

TAgId을 기존 값으로 설정하면 상관 없습니다. EF는 바보입니다. Upsert/Merge를 수행하지 않습니다. 동일한 엔티티가 있는지 여부를 확인하지 않으며 데이터베이스에 TagId이 자동으로 생성 된 경우 SaveChanges으로 전화하면 값을 버릴 수도 있습니다.

뭘해야합니까? Tag이 새 엔티티가 아니라는 것을 수동으로 EF에 알려야합니다.

시도 중 하나

Data.Shift s = new Data.Shift(); 
context.Shifts.AddObject(s); // Add a new shift 

foreach (var t in shift.Tags) 
{ //shift object is a cached object 
    Data.Tag dt = new Data.Tag 
    { 
     TagID = t.TagID, 
     Name = t.Name, 
     OrgID = t.OrgID, 
    }; 
    context.Tags.Attach(Tag); // Attach an existing tag 
    s.Tags.Add(dt); 
} 
context.SaveChanges(); 

또는

Data.Shift s = new Data.Shift(); 
foreach (var t in shift.Tags) 
{ //shift object is a cached object 
    Data.Tag dt = new Data.Tag 
    { 
     TagID = t.TagID, 
     Name = t.Name, 
     OrgID = t.OrgID, 
    }; 
    s.Tags.Add(dt); 
} 

context.Shifts.AddObject(s); 
// Now shift and all tags are added 
// Change the state of each tag to unchanged 
foreach (var tag in s.Tags) 
{ 
    context.ObjectStateManager.ChangeEntityState(tag, EntityState.Unchanged); 
} 
context.SaveChanges(); 
+0

StoreGeneratedPattern 열거 형에서 Identity 값을 사용해 보셨습니까? 상점 (데이터베이스)에서 생성 된 ID 값이 엔티티에 설정되도록해야합니다. http://msdn.microsoft.com/en-us/library/system.data.metadata.edm.storegeneratedpattern.aspx –

+0

도움 주셔서 감사합니다. Ladislav - 내 편집을 참조하십시오. – psenhancer

+0

잘못된 개체를 첨부하고 있습니다. 't' 대신에'dt'를 붙이십시오. –

관련 문제