防止在创建具有实体框架关系的其他实体时重复现有对象

本文关键字:实体 其他 对象 框架 创建 关系 | 更新日期: 2023-09-27 18:09:51

我有一个学生,他参加了由考试(1..n)组成的评估(1..n),因此学生参加了许多考试(也是1..n)。当我将评估发布到web服务时,我使用的是一个视图模型,其中包含学生对象(已经在数据库中)。我还创建了一些测试,这些测试与评估一起发送。我可以从调试器中看到,当评估到达我的web服务的后评估方法时,它附加了包括学生在内的所有内容。但是,我得到了一个409 duplicate冲突—调试器说这是一个主键冲突,不能输入duplicate。例如,如果我给学生一个新的Guid,那么一切都可以工作,关系被创建等等,但显然这创建了一个新的学生对象。我想以现有的学生为目标,建立关系。从阅读SO上的其他问题(如这里和这里)和MSDN上的这篇文章来看,我认为它与当前上下文有关,不知道现有对象并试图创建它?我试图从数据库中获得现有的学生,并将评估的学生设置为它,附加它等,但我并不是真正理解这里发生了什么。说到重复,我知道这个问题有各种各样的版本,但就像我说的,我很难理解。

 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);  
    }

防止在创建具有实体框架关系的其他实体时重复现有对象

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

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);  
}

另一个选项,你有它只是插入作业,只是维护作业的学生编号(如果模型设置正确,评估对象应该有一个学生编号属性以及一个学生属性),例如:

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);  
}

希望这就是你要找的