Entity Framework in MVVM WPF – Best Way to Wire Up Database Context

cdesign-patternsentity-frameworkmvvmwpf

As in the question above: What the best way to wire up Entity Framework database model (context) to viewModel in MVVM (WPF)?

I am learning MVVM pattern in WPF, alot of examples shows how to implement model to viewModel, but models in that examples are just simple classes, I want to use MVVM together with entity framework model (base first approach). Whats the best way to wire model to viewModel.

Thanks for answers.

//ctor of ViewModel 
public ViewModel()
{ 
db = new PackageShipmentDBEntities(); // Entity Framework generated class

ListaZBazy = new ObservableCollection<Pack>(db.Packs.Where(w => w.IsSent == false)); 
}

This is my usual ctor of ViewModel, think there is a better way, I was reading about repository pattern, not sure if I can adapt this to WPF MVVM

Best Answer

I've looked into this quite a bit and haven't found a "perfect" solution. The repository pattern works wonderfully for MVC applications where the context is short lived because it exists in a short lived controller, but the problem happens when you try to apply that same structure to a wpf app where the VM can persist for long periods of time.

I have used this solution in the past which is much more simple than many of the repo patterns I have seen that attempt to abstract things out to an extreme amount, resulting in near unreadable amounts of code that are difficult to debug. Here are the steps...

  1. Create a separate project for the EDMX to act as your Data access layer
  2. Create a "Repositories" folder under the same project
  3. Create a base class "BaseRepository" to act as the "Unit of Work". IDisposable will allow you to use this in a using(){} and the partial will allow you do implement other repositories

    public partial class MyEntityRepository : IDisposable
    {
        MyEntities context = new MyEntities();
    
        public void Dispose()
        {
            context.Dispose();
        }
    }
    
  4. Create another file called "MyOtherRepository". create the same partial class but implement methods based on what you want that file to contain

    public partial class MyEntityRepository
    {
        public void MyOtherMethodSave(EntityObject obj)
        {
            //work with context
            ...
    
            context.SaveChanges();
        }
    }
    

Now in your VM you can do this...

using(MyEntityRepository repo = new MyEntityRepository())
{
     repo.MyOtherMethodSave(objectToSave);
}

This groups all your repositories under one class so you don't have to deal with separate context. It allows you better manage different repos by grouping the methods into different files and helps prevent code duplication. On top of that, your contexts are as short lived as they were without using this pattern.

The disadvantage is that with larger systems, you may have a lot of methods that get bundled under your repo. One solution in that case would be to implement some basic common commands like "Find" or "Add", and implement specialized ones in their respective repository.