假设我们有简单的实体模型。
public class University
{
[Key]
public int Id { get; set; }
public string Name { get; set; }
public ICollection<Student> Students { get; set; }
public Employee()
{
Students = new HashSet<Student>();
}
}
public class Student
{
[Key]
public int Id { get; set; }
public int UniversityId { get; set; }
public string Name { get; set; }
public University University { get; set; }
}
让我们假设我们的表中已经有下一个数据:
University
Id: 1
Name: MIT
Student
Id: 1
UniversityId: 1
Name: Bob
-----------
Id: 2
UniversityId: 1
Name: Carl
然后我们有了一个应该更新大学的API。 假设我们通过此API收到了下一个模型
University: {
Id: 1,
Name: MIT,
Students: [
{
Id: 1,
Name: Bobby
}
]
}
此外,我们假设我们的实体具有标准的视图模型,因此它们看起来像:
public class UniversityVM
{
public int Id { get; set; }
public string Name { get; set; }
public ICollection<StudentVM> Students { get; set; }
public Employee()
{
Students = new List<Student>();
}
}
public class StudentVM
{
public int Id { get; set; }
public string Name { get; set; }
}
这些视图模型通过某些映射器(例如Automapper)映射到我们的实体,例如:
CreateMap<StudentVM, Student>();
CreateMap<UniversityVM, University>();
然后对其进行更新,我们将编写下一个代码(假设我们在断开连接的场景中工作)
public void Update (UniversityVM request) {
var existingUniversity = _context.Universities.Single(b => b.Id == request.Id);
_mapper.Map(request, existingUniversity);
_context.Update(existingUniversity);
_context.SaveChanges();
}
实际上,我们将existingUniversity.Students
替换为request.Students
,然后将其保存。因此,预期结果应该是保存所有未指定id的学生(事实如此),所有已指定id并已经存在的学生都将被更新(事实也是如此),并且最后,所有在该请求之前存在但在request.Students
中丢失的其他相关学生都应被删除(这种方式将无法正常工作)。
如果我们对其进行调试,我们将发现在_context.Univerities
ID为1的大学中将有更新的学生集合,因此,从理论上讲,EF上下文知道我们从上下文中删除了现有的学生。
但是,为什么它不删除那些没有出现在更新的收藏集中的学生呢?
该问题使我们可以手动执行删除操作,从而增加了要编写的代码。
是否有现成的方法可以实现“智能”更新?
智能更新是指我们没有编写任何代码时,默认情况下会出现以下行为:
将在嵌套集合中创建没有指定ID的实体。 嵌套集合中存在于新集合中的现有实体将被修改。 嵌套集合中未出现在新集合中的现有实体将被删除。 谢谢。