2016-04-14 43 views
1

我正在使用Web API和實體框架的小型項目中工作。我在發佈我的實體時遇到了一些問題。斷開連接的場景中的實體框架拋出保存或接受更改失敗,因爲多個實體類型

我的實體是這樣的:

public class DayExercises 
    { 
     public DayExercises() 
     { 
      Exercises = new List<Exercise>(); 
     } 
     [Key] 
     public int Id { get; set; } 

     public string Day { get; set; } 

     public virtual ICollection<Exercise> Exercises { get; set; } 

    } 

和我Exercise實體這個樣子。

public class Exercise 
    {  
     public Exercise() 
     { 
      DayExercises = new List<DayExercises>(); 
     } 
      public int Id { get; set; } 
      public string Name { get; set; } 
      public virtual List<DayExercises> DayExercises { get; set; } 
    } 

和張貼dayExercises這個樣子的

[ResponseType(typeof(WorkoutTemplate))] 
    public IHttpActionResult PostWorkoutTemplate(DayExercises dayExercises) 
    {    
     if (!ModelState.IsValid) 
     { 
      return BadRequest(ModelState); 
     } 

     foreach (var dayExercise in dayExercises) 
     { 
      fitnessDbContext.Entry(dayExercise).State = EntityState.Added; 

      foreach (var exercise in dayExercise.Exercises.ToList()) 
      { 
       fitnessDbContext.Entry(exercise).State = EntityState.Unchanged; 

      } 
     } 

     db.SaveChanges(); 

     return CreatedAtRoute("DefaultApi", new { id = dayExercises.Id }, dayExercises); 
    } 

的關係,我的網絡API方法是許多一對多。

問題: 我送一個dayExercise與現有Exercise(在數據庫中已經存在的)我的方法。但是當我發佈dayExercise與同樣的兩個練習。它會拋出該異常:

其他信息:保存或接受更改失敗,因爲類型爲「FitnessFirst.WebApi.Exercise」的多個實體具有相同的主鍵值。 確保顯式設置的主鍵值是唯一的。確保數據庫生成的主鍵在數據庫和實體框架模型中配置正確。 使用實體設計器進行數據庫優先/模型優先配置。使用代碼優先配置「HasDatabaseGeneratedOption」一口流利的API或‘DatabaseGeneratedAttribute’。

我也試圖Deattach實體,他們IDAttach他們再次使用從數據庫中獲得鍛鍊,並將其添加到dayExercise但它不保存到數據庫

注意:當我添加兩個不同的練習,它不會拋出異常

我也閱讀下面的答案,但它並沒有解決它:Ensure that explicitly set primary key values are unique

任何建議或解釋。

回答

1

我知道這是一箇舊帖子,但昨天我遇到了同樣的問題。這是我想出的解決方案。基本上實體框架變化跟蹤器只允許實體的唯一值。因此,爲了解決錯誤,您需要檢查實體是否已存在於變更跟蹤器中並使用該實例。

var excercises = dayExercise.Exercises.ToList(); 
for (int i = 0; i < excercises.Count; i++) 
{ 
    var unchangedEntity = _dbContext.ChangeTracker.Entries<Exercise>() 
     .Where(xy => xy.State == EntityState.Unchanged && 
     xy.Entity.Id == excercises [i].Id).FirstOrDefault(); 

    if (unchangedEntity == null) 
    { 
     fitnessDbContext.Entry(excercises[i]).State = EntityState.Unchanged; 
    } 
    else 
    { 
     excercises[i] = unchangedEntity.Entity; 
    } 

} 
+0

HAHA,ya這是一個很老的帖子,我在1年前達成了這個解決方案。 +1,因爲你是對的。 –

相關問題