[ОТРЕДАКТИРОВАНО]
Я ищу способ реализовать Linq To Entities в приложении WPF (MVVM) и сделать каждый View (или ViewModel) ответственным за отдельное управление своими базовыми объектами.
Вот пример простой структуры и того, чего я хотел бы достичь:
[Клиенты] (1..1) ‹----> (0..* ) [Заказы] (0..* ) ‹-- [OrderLine] --> (1..* ) [Товар]
Первое представление отображает список клиентов.
- загружает всех клиентов, но не их заказы
- позволяет создавать или удалять клиентов
Второе представление отображает сведения о покупателе и список его заказов.
- позволяет обновить свойства клиента
- загружает все заказы конкретного клиента, но не строки заказов
- позволяет создавать или удалять заказы
- может быть несколько представлений, управляющих отдельно несколькими клиентами.
Третье представление отображает детали заказа и список строк заказа.
- позволяет обновить свойства заказа
- загружает все строки заказов определенного заказа, и все продукты, связанные с этими строками заказов
- позволяет создавать или удалять строки заказов
- может быть несколько представлений, управляющих отдельно несколькими заказами.
Четвертое представление отображает сведения о продукте.
- позволяет обновить свойства продукта
- связанный продукт может быть уже загружен третьим просмотром
- может быть несколько видов, открытых одновременно и управляющих отдельно своими собственными продуктами. Я не хочу обновлять все продукты сразу, а только связанные продукты в представлении.
Согласно рекомендации Microsoft, должен быть один экземпляр DbContext для каждого экземпляра представления (или экземпляра viewModel) (https://msdn.microsoft.com/en-us/data/jj729737.aspx).
Приведенная выше схема, конечно, очень упрощена. В реальном приложении у нас будет гораздо больше сущностей и представлений. Кроме того, это могут быть разные потоки, в которых открываются представления, что затрудняет определение заранее, какие объекты уже загружены из базы данных при открытии нового представления.
Тем не менее, есть один принцип: представление (или соответствующая ViewModel) должно отвечать за обновление набора сущностей, которые оно отображает, не запрашивая DbContext для обновления сущностей, обрабатываемых другим представлением.
ВОПРОСЫ
DbContext productView должен иметь возможность передавать изменения в связанном продукте в базу данных. Однако он не должен загружать продукт из базы данных, если он уже был загружен ранее (то есть с помощью DbContext, связанного с orderLinesView). Проблема в том, что DbContext, насколько я понимаю, инкапсулирует транзакцию, что заставляет меня думать, что вряд ли он может нести ответственность за сохранение сущностей, которые он не загрузил сам по себе ранее. Как решить такую проблему?
Совершенно очевидно, что у меня должен быть экземпляр DbContext для каждого экземпляра представления, чтобы функция SaveChanges() обрабатывала только данные текущего представления. Что неясно, так это то, что у меня должно быть несколько классов, наследующих DbContext, или один класс, представляющий DbContext приложения.
Нужно ли добавлять свойство DbSet‹> в DbContext для каждого типа объекта, который мы хотим обновить? Похоже, что DbContext нужно будет постоянно менять по мере роста приложения с новыми сущностями. Кроме того, это означает повторяющийся код в моделях представления, чтобы указать, какой DbSet‹> должен быть загружен, и т. д. Не было бы более эффективным иметь механизм (1), который может получать набор сущностей для обновления (независимо от их типа). ) и еще один механизм (2), позволяющий выбрать набор сущностей для передачи механизму (1)? Второй механизм может быть либо ручным (для гибких сценариев), либо автоматическим (например, путем просмотра всех сущностей, перечисленных в ViewModel).
Если я хочу поместить механизм доступа к базе данных в веб-службу, как я могу продолжать управлять их базовыми сущностями каждого представления отдельно? В таком случае, где и как следует создавать экземпляры DbContexts?
Я с нетерпением жду любых советов, которые вы можете дать.