views:

62

answers:

1

If I expose my EF 4 Model objects (EF4 entities) as properties on my ViewModel am I "breaking" MVVM ?

Do I have to duplicate each Model class as some sort of DTO and expose those DTOs from the ViewModel ?

I understand the theoretical value of having the View "not know" about the Model, but the reality is that (if I don't expose the Model to the View via the ViewModel) I'd have to have some classes that have the same properties as the Model classes to bind to. Then, in the ViewModel, I'd have to scrape the properties of those DTO-ish objects to update appropriate EF Entities (Model).

This seems like a lot of extra code to write and maintain. If I expose the Entities as properties on my ViewModel (and bind to that), I can still use Commands (i.e. for saving or deleting) that have their code/logic in the ViewModel and enabled/disabled state set via binding to ViewModel properties.

If you are wondering: "What's the big deal with having to write one or two DTO's for your ViewModel ?" You are thinking too small.

I have an application with 75+ SQL Tables (and therefore 75+ EF4 entities). I don't fancy the idea of having to write and maintain 75+ DTOs. Now I could possibly use T4 to generate DTOs for all my entities and even have it generate partial classes so that I can "customize" these generated DTOs without losing the customizations if I have to regenerate. Still, I need to feel it is "worth it" to do all that... and I'm not sure about that yet.

Thoughts ?

A: 

We also faced this problem with about 200 Entities in the model. Since the databinding directly writes back into the model, the ViewModel infact has no more control for these changes to the db entities. At the moment, we have figured out a solution, which we will implement in the next refactoring cycle. We also use T4 templates to improve some EF feature lacks. So our idea is to have a ViewEntity and a DbEntity. For this, you dont have to create/generate another DTO class. If you instanciate a new Entity, without adding it to the ObjectContext, its behavior is like a simple DTO.

So our solution will be:

  • download and bind the db entities to the context (we are using CLR Stored Procedures and T4 generated Materializers)

  • create a new view Entity for each entity, which will be exposed to the view, using a T4 generated Clone() method, which returns an unbound version of the db entity.

Now you have complete control for writing back changes or undoing changes in your viewmodel, since databinding to the view entity does not affect the db entity.

JanW
Would you please explain more about the T4 generated clone method ?
Craig L
You have to analyze the model information for each entity, extract information about all primitive properties, except primary keys which you will not reproduce in the Clone method. Then you need to create the new entitiy and copy all its primitive properties from the given DB entity. The signature will be something like this: public static TEntity Clone(TEntity dbEntity); Where TEntity is the fullname of the current entity. If you need code example ask again
JanW