实体框架核心更新嵌套集合(在视图模型和实体之间使用映射器)

时间:2020-02-28 18:47:21

标签: entity-framework automapper

假设我们有简单的实体模型。

    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的实体。 嵌套集合中存在于新集合中的现有实体将被修改。 嵌套集合中未出现在新集合中的现有实体将被删除。 谢谢。

0 个答案:

没有答案