10

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

0

3 Answers 3

5

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.

2
  • 2
    You can replace 'MyEntityRepository' EF's own context and you get the same result. Unless you want to wrap EF's context with your own "repository", increasing duplication.
    – Euphoric
    Oct 24, 2013 at 6:35
  • @Euphoric Yeah you could, but then you aren't guaranteed that the repository is used over the context. The whole point is to abstract away the way EF works into simple business requirements Oct 24, 2013 at 12:53
4

Opposed to repositories, which I don't like. I would recommend using Command pattern, as recommended by Ayende.

Simply said, for each operation, you create a separate ThisOperationCommand class. Inside this class you will work with normal EF context. You might even use some base class EFCommand that does some plumbing for you.

From ViewModel side, you create instance of this command, fill it with parameters (you can even pass whole ViewModel instance if you don't mind tight coupling between the command and ViewModel) and then pass it to some kind of Execute method, that will start up the command, execute it, tear it down and then return whatever the command got. You can also have it return multiple values if you get it from instance of the command after execution.

The advantage is that you don't need to duplicate the whole data access layer as reposotory and you can reuse and compose commands as long as you create some simple infrastructure to support it. For example executing commands from other commands.

1

For simple scenarios I've used the following:

public class ViewModel : IDisposable {

    private EntitiesContext _context = new EntitiesContext();

    private SomeEntity _model;
    public SomeEntity Model {
       get { return _model; }
    }

    public View(int id) {
        _model = _context.SomeEntity.Find(id);
    }

    private ICommand _saveCommand = new RelayCommand(() => _context.SaveChanges());
    public ICommand SaveCommand {
        get { return _saveCommand; }
    }        

    public void Dispose() {
         _context.Dispose();
    }

}
2
  • 1
    The problem with this is that your context is now potentially "long living". Oct 30, 2013 at 16:00
  • 1
    You shouldn't be creating the instance of the context inside the class, but injecting it in the constructor instead. Nov 25, 2013 at 3:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.