Как лучше всего связать контекст (модель) базы данных Entity Framework с ViewModel в MVVM WPF?
9
Как и в приведенном выше вопросе: Как лучше всего связать модель базы данных Entity Framework (контекст) с viewModel в MVVM (WPF)?
Я изучаю шаблон MVVM в WPF, на многих примерах показано, как реализовать модель для viewModel, но модели в этих примерах являются просто простыми классами, я хочу использовать MVVM вместе с моделью структуры сущностей (базовый подход вначале). Какой лучший способ связать модель с viewModel.
Спасибо за ответы.
//ctor of ViewModel publicViewModel(){
db =newPackageShipmentDBEntities();// Entity Framework generated classListaZBazy=newObservableCollection<Pack>(db.Packs.Where(w => w.IsSent==false));}
Это мой обычный ctor ViewModel, думаю, что есть лучший способ, я читал о шаблоне хранилища, не уверен, смогу ли я адаптировать это к WPF MVVM
Я немного разбирался в этом и не нашел «идеального» решения. Шаблон репозитория прекрасно работает для приложений MVC, где контекст недолговечен, поскольку существует в недолговечном контроллере, но проблема возникает, когда вы пытаетесь применить эту же структуру к приложению wpf, где виртуальная машина может сохраняться в течение длительных периодов времени.
В прошлом я использовал это решение, которое было намного проще, чем многие из шаблонов репо, которые я видел, пытаясь абстрагировать вещи до предела, что приводит к почти нечитаемому объему кода, который трудно отладить. Вот шаги ...
Создайте отдельный проект для EDMX, который будет выступать в качестве слоя доступа к данным.
Создайте папку «Репозитории» под тем же проектом
Создайте базовый класс «BaseRepository», который будет действовать как «Единица работы». IDisposableпозволит вам использовать это в using(){}и partialпозволит вам реализовать другие репозитории
Создайте другой файл с именем «MyOtherRepository». создать тот же частичный класс, но реализовать методы, основанные на том, что вы хотите, чтобы этот файл содержал
publicpartialclassMyEntityRepository{publicvoidMyOtherMethodSave(EntityObject obj){//work with context...
context.SaveChanges();}}
Теперь в вашей виртуальной машине вы можете сделать это ...
Это группирует все ваши репозитории под одним классом, поэтому вам не нужно иметь дело с отдельным контекстом. Это позволяет вам лучше управлять различными репозиториями, группируя методы в разные файлы, и помогает предотвратить дублирование кода. Кроме того, ваши контексты так же недолговечны, как и без использования этого шаблона.
Недостатком является то, что в более крупных системах у вас может быть много методов, связанных с вашим репо. Одним из решений в этом случае было бы реализовать некоторые основные общие команды, такие как «Найти» или «Добавить», и внедрить специализированные команды в их соответствующие хранилища.
Вы можете заменить собственный контекст EF «MyEntityRepository», и вы получите тот же результат. Если вы не хотите обернуть контекст EF своим собственным «хранилищем», увеличивая дублирование.
Эйфорическая
@Euphoric Да, вы могли бы, но тогда вы не гарантированы, что хранилище используется в контексте. Весь смысл в том, чтобы абстрагироваться от того, как EF работает с простыми бизнес-требованиями
Shoe
4
В отличие от хранилищ, которые мне не нравятся. Я бы порекомендовал использовать шаблон Command, как рекомендовано Ayende .
Проще говоря, для каждой операции вы создаете отдельный ThisOperationCommandкласс. Внутри этого класса вы будете работать с обычным EF-контекстом. Вы могли бы даже использовать некоторый базовый класс, EFCommandкоторый делает некоторые сантехнические работы для вас.
Со стороны ViewModel вы создаете экземпляр этой команды, заполняете его параметрами (вы можете даже передать весь экземпляр ViewModel, если не возражаете против тесной связи между командой и ViewModel), а затем передаете его какому-то Executeметоду, который запустится выполнить команду, выполнить ее, разорвать и вернуть то, что получила команда. Вы также можете сделать так, чтобы он возвращал несколько значений, если вы получили его из экземпляра команды после выполнения.
Преимущество состоит в том, что вам не нужно дублировать весь слой доступа к данным в качестве репозитория, и вы можете повторно использовать и составлять команды, если вы создаете некоторую простую инфраструктуру для их поддержки. Например, выполнение команд из других команд.
В отличие от хранилищ, которые мне не нравятся. Я бы порекомендовал использовать шаблон Command, как рекомендовано Ayende .
Проще говоря, для каждой операции вы создаете отдельный
ThisOperationCommand
класс. Внутри этого класса вы будете работать с обычным EF-контекстом. Вы могли бы даже использовать некоторый базовый класс,EFCommand
который делает некоторые сантехнические работы для вас.Со стороны ViewModel вы создаете экземпляр этой команды, заполняете его параметрами (вы можете даже передать весь экземпляр ViewModel, если не возражаете против тесной связи между командой и ViewModel), а затем передаете его какому-то
Execute
методу, который запустится выполнить команду, выполнить ее, разорвать и вернуть то, что получила команда. Вы также можете сделать так, чтобы он возвращал несколько значений, если вы получили его из экземпляра команды после выполнения.Преимущество состоит в том, что вам не нужно дублировать весь слой доступа к данным в качестве репозитория, и вы можете повторно использовать и составлять команды, если вы создаете некоторую простую инфраструктуру для их поддержки. Например, выполнение команд из других команд.
источник
Для простых сценариев я использовал следующее:
источник