我正在使用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
的web api方法看起来像这样
[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);
}
这种关系是多对多的。
问题:
我正在向我的方法发送一个dayExercise
,其中包含现有Exercise
(已存在于数据库中)。但是当我发布dayExercise
和SAME两个练习时。它抛出了这个例外:
其他信息:保存或接受更改失败,因为多个类型为&#39; FitnessFirst.WebApi.Exercise&#39;的实体具有相同的主键值。 确保显式设置的主键值是唯一的。确保在数据库和Entity Framework模型中正确配置了数据库生成的主键。 使用实体设计器进行数据库优先/模型优先配置。使用&#39; HasDatabaseGeneratedOption&#34;流利的API或“DatabaseGeneratedAttribute”#39;代码优先配置。
我还尝试了Deattach
个实体,然后再次使用他们的ID
和Attach
从数据库中获取练习并将其添加到dayExercise
,但它没有&# 39;保存到数据库。
注意:当我添加两个不同的练习时,它不会抛出异常。
我也阅读了以下答案,但它没有解决它:Ensure that explicitly set primary key values are unique
任何建议或解释。
答案 0 :(得分: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;
}
}