2016-10-02 31 views
0

我有一个学生参加由测验(1..n)组成的评估(1..n),因此学生需要进行很多测试(也是1..N)。当我将评估发布到Web服务时,我正在使用具有学生对象(已经在数据库中)的视图模型。我还创建了一些与评估一起发送的测试。 从调试器中我可以看到,当评估到达我的Web服务的后评估方法时,它包含了所有内容,包括学生。但是,我得到了409个重复的冲突 - 调试器说这是一个主键违规无法输入重复。例如,如果我给学生一个新的Guid,那么一切正常,关系创建等等,但显然这会创建一个新的学生对象。 我想瞄准现有的学生并建立关系。 从阅读SO上的其他问题(如herehere)和本文MSDN,我认为它与当前上下文不知道现有对象有关,它试图创建它?我试图从db中获得现有的学生,并将评估的学生设置为它,附加它等,但我并不真正了解这里发生的事情。 说到重复,我明白在这里有这个问题的各种版本,但就像我说的,我很难理解。防止在创建具有实体框架关系的其他实体时重复现有对象

public async Task<IHttpActionResult> PostAssessment(Assessment item) 
    { 
     using (var context = new DBContext()) 
     { 
      Student theStudent = context.Students.Single(s => s.Id == item.Student.Id); 
      item.Student = theStudent; 
      //context.Students.Attach(theStudent); 
      context.Entry(theStudent).State = EntityState.Modified; 
      context.SaveChanges(); 
     } 
     Assessment current = await InsertAsync(item); 
     return CreatedAtRoute("Tables", new { id = current.Id }, current); 
    } 

这是错误的。

回答

1

从你的代码中,我们不清楚关系的另一面是怎样的,但我认为它看起来像(在学生对象上):theStudent.Assessments?在这种情况下,我宁愿将评估添加到学生,而不是将学生添加到评估中。例如:

public async Task<IHttpActionResult> PostAssessment(Assessment item) 
{ 
    using (var context = new DBContext()) 
    { 
     Student theStudent = context.Students.Single(s => s.Id == item.Student.Id); 
     item.Student = null;//Just to make sure there is not other relationship here 
     //because 'theStudent' was retreived from the db it will be in the change graph so any changes will be recoreded 
     theStudent.Assessments.add(item);//I am assuming it should be added because it is a POST method 
     context.SaveChanges(); 
    } 
    Assessment current = await InsertAsync(item); 
    return CreatedAtRoute("Tables", new { id = current.Id }, current); 
} 

你拥有它只需插入任务,只是保持对分配的StudentId(如果该模型建立正确的评估对象应该有一个StudentId属性,以及一个学生属性的另一种选择)例如:

public async Task<IHttpActionResult> PostAssessment(Assessment item) 
{ 
    using (var context = new DBContext()) 
    { 
     Student theStudent = context.Students.Single(s => s.Id == item.Student.Id); 
     item.StudentId = item.Student.Id; 
     item.Student = null; 
     //context.Students.Attach(theStudent); 
     context.Assemssments.Add(item); 
     context.SaveChanges(); 
    } 
    Assessment current = await InsertAsync(item); 
    return CreatedAtRoute("Tables", new { id = current.Id }, current); 
} 

希望这是同期寻找的。

+0

嗨,谢谢你的帮助。这并不能完全解决上下文问题,但将学生从评估中移除并替换为现有对象并将评估添加到学生而不是反之亦然的逻辑起作用。据我了解,解决方案,如上所述,仍然会导致一个问题,因为有两种不同的上下文在运行。谢谢你的帮助。 – Inkers

相关问题