【发布时间】:2016-01-17 03:20:45
【问题描述】:
我首先使用 MVC 5 和实体框架代码。
我有一个附有学生列表的班级(学校班级)对象,我正在尝试更新班级和/或班级中的学生以及当我在上下文中调用 SaveChanges() 时得到的内容是班级学生的重复记录。基本上,旧的学生列表在数据库中被“孤立”了,而一组全新的学生将附加到数据库中已编辑的班级。
因此,我现在有 20 个学生记录,而不是数据库中的 10 个更正学生记录。 10 个原始(未更正)和 10 个新(已更正)。 10 个原始的已删除 classid 外键,因此它们不再属于该类。
对 Class 对象的任何更新都可以很好地实现,而不会复制 Class 记录。
我看到一个答案表明,可能上下文不知道学生不是新项目,所以它添加了它们......并从数据库中获取学生以便上下文知道他们 - 但是如果当你从数据库中拉出类对象时,学生会来,这和直接拉出不一样吗?
public class Class
{
[Key]
public Guid ClassId { get; set; }
[Display(Name="Class Name")]
public string ClassName { get; set; }
public virtual List<Student> Students { get; set; }
public virtual Teacher Teacher { get; set; }
public Class()
{
ClassId = Guid.NewGuid();
Students = new List<Student>();
}
}
[HttpPost]
public ActionResult Edit(Guid id, FormCollection collection)
{
Class selectedclass = db.Classes.Find(id);
try
{
UpdateModel(selectedclass, collection.ToValueProvider());
db.SaveChanges();
return RedirectToAction("Details", new { id = id });
}
catch
{
return View(selectedclass);
}
}
我到底做错了什么?
我唯一能想到的就是在我保存更改之前删除数据库中附加到该班级的所有学生记录,但必须有比这更好的方法。
db.Students.RemoveRange(db.Classes.Find(id).Students);
所以我尝试将列表中的学生附加到上下文中,甚至将他们的状态更改为已修改,例如:
selectedclass.Students.ForEach(s => db.Students.Attach(s));
selectedclass.Students.ForEach(s => db.Entry(s).State = EntityState.Modified);
但没有运气,仍然会出现重复和孤儿。
尝试直接从数据库中获取学生,但没有成功:
var ids = selectedclass.Students.Select(s => s.StudentId).ToList();
selectedclass.Students = db.Students.Where(s => ids.Contains(s.StudentId)).ToList()
学生编辑器的 HTML:
@for (int i = 0; i < Model.Students.Count; i++)
{
<div class="col-md-8">
@Html.EditorFor(m => m.Students[i], new { htmlAttributes = new { @class = "form-control" }})
</div>
}
学生编辑器模板:
<div class="form-group">
@Html.LabelFor(m => m.FirstName, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-xs-6 col-md-4">
@Html.EditorFor(m => m.FirstName, new { htmlAttributes = new { @class = "form-control" }})
</div>
@Html.LabelFor(m => m.LastName, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-xs-6 col-md-4">
@Html.EditorFor(m => m.LastName, new { htmlAttributes = new { @class = "form-control" }})
</div>
</div>
<div class="form-group">
@Html.LabelFor(m => m.UserName, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-xs-6 col-md-4">
@Html.EditorFor(m => m.UserName, new { htmlAttributes = new { @class = "form-control" } })
</div>
@Html.LabelFor(m => m.Password, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-xs-6 col-md-4">
@Html.EditorFor(m => m.Password, new { htmlAttributes = new { @class = "form-control" }})
</div>
</div>
【问题讨论】:
-
在使用
UpdateModel()前后检查selectedclass的值 -
@StephenMuecke 他们从原来的样子变成了我希望他们更新的样子……没有问题。只是新列表像一个全新的列表一样添加到数据库中,而不是更新现有的学生列表。
-
但是您在问题中指出 ClassId 属性已被删除?
-
@StephenMuecke - 我的解释不好......被清除的属性在学生对象上,有效地将学生从课堂上移除。它是在数据库中的现有学生上完成的,而不是我正在使用的班级所附列表中的学生。
-
问题可能出在您的数据库代码上 - 但您没有提供详细信息。可以假设实体框架,然后您可能会遇到分离实体问题,但由于您没有提供任何细节,这只是一个疯狂的猜测。
标签: c# entity-framework asp.net-mvc-5 ef-code-first