views:

750

answers:

6

I am investigating WPF's MVVM design pattern. But am unsure where to put the Data Acess code?

In some examples I have looked at, data access is performed directly in the ViewModel. It seems odd to put something like linq to sql in the ViewModel? Other examples have a seperate project for Data Access, this seems more like it?

Is this there a general approach? I feel like I am missing something here!

Thanks

+3  A: 

I would add another layer, essentially what you want is a data factory. You want to create a set of classes that will CRUD to the database for you and return clean POCO objects to the ViewModel.

A good example to look at would the Nerd Dinner book. It covers MVC not MVVM but the patterns are very similar and the way they access data in that solution would be good starting point.

Hope this helps.

Lukasz
Thanks. I like the way Nerd Dinner uses the Repository pattern (as also suggested by Kristoffer). In terms of file structure I think I will seperate out the Repository class and associated mappers to a Data Access directory. Still seems as though it is a large area that goes largly unmentioned in MVVM. Thanks again.
Dan Black
The NerdDinner example is indeed a good example of the repository pattern. They do however expose the domain model in the views (i.e. they don't use MVVM), which is considered bad practice.
Kristoffer
+2  A: 

MVVM stands for Model, View, and ViewModel. The piece you are missing is the Model, which is where your data access code lives.

The ViewModel takes the Model and presents it to the View for display, so typically you would have something like this:

class PersonModel : IPerson
{
    // data access stuff goes in here
    public string Name { get; set; }
}

class PersonViewModel
{
    IPerson _person;

    public PersonViewModel(IPerson person)
    {
        _person = person;
    }

    public Name
    {
        get { return _person.Name; }
        set { _person.Name = value; }
    }
 }

The PersonView would then bind to the properties of the PersonViewModel rather than directly to the model itself. In many cases you might already have a data access layer that knows nothing about MVVM (and nor should it) but you can still build ViewModels to present it to the view.

GraemeF
Choose this one.
eskerber
Check out http://jonas.follesoe.no/YouCardRevisitedImplementingTheViewModelPattern.aspx
eskerber
+4  A: 

Data access should not be in the view model, as this is supposed to be a view specific (possibly simplified) representation of the domain model.

Use a mapper of some sort to map your view model (the VM in MVVM) to your model (the first M). New objects in your model can be created using the factory pattern. Once created, you can store them in a database using the repository pattern. The repositories would then represent your data access layer. In your repository you could use an O/R mapper like NHibernate or Entity Framework.

EDIT:
I see that GraemeF suggests putting the data access code in the model. This is a NOT a good approach, as this would force you to update your domain model if you were to move from e.g. SQL Server to Oracle or XML files. The domain objects should not have to worry about how they are persisted. The repository pattern isolates the domain from its persistence.

Kristoffer
Good point; of course you can take it a lot further. My point is that the data access code is hidden behind that interface and doesn't live in the ViewModel.
GraemeF
A: 

Your ViewModel should be a thin layer that just services the view. My rule of thumb: if it has to do with the presentation of the UI, then it belongs in the ViewModel, otherwise it should be in the Model.

Ryan Emerle
+3  A: 

Here's how I've been organizing my MVVM w/ LINQ projects:

Model - I think of the Model as the state of the system. It provides an interface to the data, and it keeps track of system status. The Model does not know about the ViewModel or View--it just provides a public interface to its data and various events to let the consumers (usually ViewModels) know when the state has changed.

ViewModel - The ViewModel is in charge of organizing or structuring all the data needed by the View, keeping track of the status of the view (such as the currently selected row of a data grid), and responding to actions on the view (such as button pushes). It knows what the view needs, but it doesn't actually know about the view.

View - The View is the actual look and feel of the UI. It contains all the built-in and custom controls, how they arranged, and how they are styled. It knows about the ViewModel, but only for the purpose of binding to its properties.

Gateway - This is the part that directly addresses your question. The Gateway (which is basically my way of saying "DataAccessLayer") is its own separate layer. It contains all the code (including LINQ queries) to CRUD or select, insert, update, and delete data from/to your data source (database, XML file, etc.). It also provides a public interface to the Model, allowing the Model to focus on maintaining system state without having to concern itself with the details (i.e., the queries) needed to update the data source.

DataAccess Classes - In C#, these are very simple classes that model your elemental data objects. When you select something using a LINQ query, you will usually create an IEnumerable<T> or List<T> where T is one of your data objects. An example of a data object would be:

public class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
}

The big advantage of a design like this is that it really separates your concerns. Everything has a specialized job, and it's (usually) pretty easy to know what kind of thing goes where.

The disadvantage is that it may be overkill for small projects. You end up creating a lot of infrastructure for public interfaces that basically pass a single wish through several layers. So, you might end up with a scenario like this: [user clicks Submit, ViewModel tells Model to AddNewPerson, Model tells Gateway to InsertPerson] instead of a scenario like this [user clicks Submit, ViewModel adds new record to the database directly].

Hope that helps.

DanM
A: 

The WPF Application Framework (WAF) contains a sample application that shows how the Model-View-ViewModel (MVVM) pattern might be used in combination with the Entity Framework.

jbe