views:

300

answers:

2

I have a WPF application built using the MVVM pattern:

  • My Models come from LINQ to SQL.
  • I use the Repository Pattern to abstract away the DataContext.
  • My ViewModels have a reference to a Model.
  • Setting a property on the ViewModel causes that value to be written through to the Model.

As you can see, my data is stored in my Model, and changes are therefore tracked by my DataContext.

However, in this question I read:

The guidelines from the MSDN documentation on the DataContext class are what I would recommend following:

In general, a DataContext instance is designed to last for one "unit of work" however your application defines that term. A DataContext is lightweight and is not expensive to create. A typical LINQ to SQL application creates DataContext instances at method scope or as a member of short-lived classes that represent a logical set of related database operations.

How do you track your changes? In your DataContext? In your ViewModel? Elsewhere?

+1  A: 

When I write this kind of software, my VMs never have a reference in any way to the data model. When you couple them like this, you are pretty much married to a simple two-tier solution which can be really tough to break out.

If you disconnect the DataContext entirely from your VM and have them live on their own, your application becomes:

  • Much more testable -- your VMs can be tested without the datacontext
  • Potentially stateless at the data layer -- it's easy to change your architecture to adopt a stateless 3-tier based solution.
  • Able to easily integrate other data sources -- your VMs can elegantly contain aggregates and combinations of other data sources on their own.

So in short, yes, I would recommend decoupling the data access classes from the ViewModel objects throughout the app. It might be a bit more code, but it will pay dividends down the road with the architecture's flexibility.

EDIT: I don't use the change tracking features of the L2SQL objects once they've crossed a distribution boundary. That turns into a can of worms pretty quickly -- you can spend a lot of time with the care and feeding of your data model's object graph inside your viewmodel - which adds not only complexity to the ViewModel, but at least transitively couples the ViewModel to the schema of the database. Instead of doing that, I make the ViewModel pure. When the time comes for them to be persisted, your service layer/repository/whatever does the translation between the ViewModel and the data objects. This at first seems like a lot of work, but for anything other than simple CRUD, this design pays off pretty quickly.

Dave Markle
Just to clarify - my ViewModels know nothing about the DataContext. I use the repository pattern to abstract that away. Doesn't that give me the advantages you mentioned? Sorry I didn't mention this, I will edit the question.
Groky
I'm really struggling on how you'd track changes if you're not using the DataContext to do this. Could you elaborate?
Groky
Essentially what he is talking about is having a repository that returns a "common" object that your DL and VM both understand, this is essentially the middle ground. In most cases it will almost 100% reflect your DM, but as your application grows your DM and BM or Business Model could potentially separate quite a bit. You will need some amount of translation in the middle, but with LinqToObjects it is pretty easy to do. The Context tracking is done by submitting an object for save and translating that object to your DM object which has Context. The asp.net MVC store sample uses this.
Tom Anderson
A: 

However you manage data inside a program, instances of objects of L2SQL generated classes are created like regular objects, without any using of a data context. DataContext is only responsible for interacting with a database.

Those guidelines may mean that you can do anything with objects of L2SQL generated classes, but don’t keep an object that transfers data between them and a database. You can treat L2SQL classes like any other classes, which you can use as you want, with an additional capability of being read from and written to a database.

This is a guess. I cannot say what was in the head of the MSDN author of that magic phrase, but this explanation makes sense. Store data in L2SQL generated classes objects during the whole program’s activity and synchronize it with database by temporary DataContext objects.

Dmitry Tashkinov
That sound great in practise, but have you ever tried using entities from one DataContext with another? Not exactly easy.
Groky
Honestly, I don't remember if I've ever done so or not. It's going interesting. I can check, but to save time, can you tell in short, what's the problem with it?
Dmitry Tashkinov