Вложенная коллекция обновлений ядра Entity Framework (с использованием сопоставления между моделями представления и сущностями) - PullRequest
0 голосов
/ 28 февраля 2020

Предположим, у нас есть простая модель сущности.

    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 и затем сохранили его. Таким образом, ожидаемый результат должен состоять в том, что все ученики, у которых нет указанного идентификатора, должны быть сохранены (так будет), все ученики, у которых указан идентификатор и уже существует, будут обновлены (и так будет) наконец, все остальные связанные студенты, которые существовали до этого запроса, но отсутствуют в request.Students, должны быть удалены (и это не будет работать таким образом).

Если мы отладим это, мы обнаружим, что в * В университете 1024 * с идентификатором 1 будет обновлена ​​коллекция студентов, поэтому теоретически контекст EF знает, что мы удалили существующих студентов из контекста.

Но почему он не удаляет тех студентов, которые не представлены в обновленном коллекция больше?

Эта проблема заставляет нас выполнять операцию удаления вручную, что увеличивает объем кода для записи.

Существует ли какой-либо существующий способ добиться "умного" обновления из коробки?

Умное обновление - это когда мы не пишем никакого кода, и по умолчанию будет следующее поведение:

Объекты в Будет создана вложенная коллекция, у которой нет указанного идентификатора. Существующие сущности во вложенной коллекции, представленные в новой коллекции, будут изменены. Существующие сущности во вложенной коллекции, которые не представлены в новой коллекции, будут удалены. Спасибо.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...