2015-01-23 5 views
0

엔티티가 ExhibitExhibition인데,이 엔티티는 다 대다 관계입니다. Exhibit도 많은 카테고리를 가질 수 있습니다.탐색 속성이있는 엔티티를 연결할 때 예외가 발생했습니다.

나는 새로운 전시회를 만드는거야
public class ExhibitionModel 
{ 
    public ExhibitionModel() 
    { 
     this.Exhibits = new List<ExhibitModel>(); 
    } 

    [Key] 
    public int ExhibitionId { get; set; } 

    //some props 

    public virtual IList<ExhibitModel> Exhibits { get; set; } 
} 

public class ExhibitModel 
{ 
    [Key] 
    public int ExhibitId { get; set; } 

    //some props 

    public virtual IList<CategoryModel> Categories { get; set; } 
    public virtual IList<ExhibitionModel> Exhibitions { get; set; } 
} 

public class CategoryModel 
{ 
    [Key] 
    public int CategoryId { get; set; } 

    public virtual IList<ExhibitModel> Exhibits { get; set; } 
} 

내 뷰 모델에 나는 전시 ID를 선택 포함 된 모든 전시 매개 변수와 문자열을 가지고있다.

public ActionResult Create(CreateExhibitionViewModel model) 
    { 
     try 
     { 
      if (ModelState.IsValid) 
      { 
       if (!String.IsNullOrEmpty(model.ExhibitsString)) 
       { 
        model.Exhibition.AddExhibitsToModel(model.ExhibitsString, exhibitsRepo); 
       } 

       var result = exhibitionsRepo.Create(model.Exhibition); 
       if (result != null) 
       { 
        return RedirectToAction("Index"); 
       } 
      } 
      return View(model); 
     } 
     catch 
     { 
      return View(); 
     } 
    } 

    public static void AddExhibitsToModel(this ExhibitionModel model, string exhibitsString, ExhibitsRepository exhibitsRepo) 
    { 
     if (!String.IsNullOrEmpty(exhibitsString)) 
     { 
      string[] ids = exhibitsString.Split(','); 
      foreach (string stringId in ids) 
      { 
       int id; 
       ExhibitModel exhibit = new ExhibitModel(); 
       if (int.TryParse(stringId, out id)) 
       { 
        exhibit = exhibitsRepo.Read(id); 
       } 

       model.Exhibits.Add(exhibit); 
      } 
     } 
    } 

그리고 당신이 볼 수 있듯이, 나는 새 레코드를 만들지 않도록하기 위해 모든 전시 엔티티를 부착하고있어 ExhibitionRepository

public ExhibitionModel Create(ExhibitionModel exhibition) 
    { 
     try 
     { 
      using (var dbContext = new MuseumContext()) 
      { 
       foreach (var exhibit in exhibition.Exhibits) 
       { 
        if (exhibit.ExhibitId != 0 && dbContext.Entry(exhibit).State == EntityState.Detached) 
        { 
         dbContext.Exhibits.Attach(exhibit); 
        } 
       } 

       var result = dbContext.Exhibitions.Add(exhibition); 
       dbContext.SaveChanges(); 
       return result; 
      } 
     } 
     catch (Exception ex) 
     { 
      return null; 
     } 
    } 

에서 Create 방법. 두 개의 전시가 같은 범주를 가지고있는 경우 두 번째 전시 던지기 예외를 붙이는 경우

'Project.Models.CategoryModel'유형의 엔티티를 부착하는 것은 동일한 유형의 다른 엔티티가 이미 동일한 기본 키 값을 가지고 있기 때문에 실패했습니다. 이것은 'Attach'방법을 사용하거나 그래프의 엔티티 중 하나가 충돌하는 키 값을 갖는 경우 엔티티의 상태를 '변경되지 않음'또는 '수정 됨'으로 설정할 때 발생할 수 있습니다. 이는 일부 엔티티가 새롭고 아직 데이터베이스 생성 키 값을 수신하지 않았기 때문일 수 있습니다. 이 경우 'Add'메소드 또는 'Added'엔티티 상태를 사용하여 그래프를 추적 한 다음 비 신규 엔티티의 상태를 'Unchanged'또는 'Modified'로 적절하게 설정하십시오.

이 문제를 해결하려면 어떻게해야합니까?

감사합니다, 콘라드

답변

0

엔티티가 이미 EF 추적 할 때이 오류는 일반적으로 발생합니다. 여기에있을 것으로 생각됩니다 :

exhibit = exhibitsRepo.Read(id); 

두 가지 옵션이 있습니다.

  1. AsNoTracking()으로 읽기 방법을 설정할 수 있습니다. 아마 db.Exhibits.AsNoTracking().Where(x => x.Id== id);

    이 방법을 사용하면 명시 적으로 엔티티를 추적하지 않도록 EF에게 알립니다.

  2. 전시회가 이미 데이터베이스에있는 경우 전시회 컬렉션에 추가하고 변경 사항을 저장하기 만하면 EF가 귀하를 대신하여 참조 자료를 작성하여 전시회 기록에 저장해야합니다. 엔티티를 다시 연결할 필요가 없습니다.

관련 문제