2016-04-14 41 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,因为你是对的。 –

相关问题