Question

Given an MVC3 app using the ViewModel pattern and the Repository pattern with Entity Framework.

If I have a create and update view each composed of multiple entities,  what is the best practice for saving the data?

Should I save the date using an abstracted service layer which will save the data for each entity with its respective repository or should I save the data in the repository using a stored procedure?

I'm open to any suggestions or recommendations.

Thanks in advance!

Was it helpful?

Solution

This is one of those cases where a DDD/CQRS approach makes most sense. Simply put, you have some business objects which models a specific behavior (an aggregate). There is one object in chrage called the Aggregate Root (AR) which has explicit boundaries. When you want to save it, you send the whole AR to the repository which then saves everything as a transaction.

The workflow

User sends the data via a view model. The controller will then retrieve the AR from the repository or creates if it's new . THe input data is mapped to the AR, usually via an AR method. IF the AR finds that the data or the result of it, breaks some business rules then it should throw an exception (we assume that basic validation was already performed automatically by asp.net mvc).

If everything is ok, the controller will send the AR to the repo which then it will proceed to map the AR to EF entities and then saves it, all within a transaction.

THis is in a nutshell how I'd do it. Of course, I'd actually implement it a bit different, but the concepts are the same. THe important part is to send all the data to the AR which will know how to handle relationships.

Important points

Note that I've mentioned EF only after the AR got to the repo. This means, the AR has no relation to EF entities is completely separated and serves the actually business model. Only after the model is updated, we care about EF and ONLY within the repo (because EF is an implementation detail of the repo). The repo only transfers (maps basically) AR data to the relevant EF entities and then saves the entities.

It's important to have a very clear distinction between the business (domain) model and the persistence modewl (EF entities). Don't use EF to handle business rules, use it only to stare/retrieve data from db. EF was made to abstract RDBMS access only, use it as a virtual OOP database.

You've mentioned the ViewModel pattern. I haven't heard about such a pattern, everytime you're using MVC you're already using ViewModels. One again, the trick is NOT to use EF entities as ViewModels. Use 'dumb' view models fitted for the views. Populate the VM via a specialized Queries repository which will return directly VM parts. The repo will query EF entities and then return those VM bits which are simple DTO's. That's because you don't need validation and business rules when showing data.

I think it is a good practice to keep the layers and especially each layer's model separated. For updating stuff, use complex business objects(domain model) which will do the hard work and then only transfer their state to EF (via repository). For reading stuff, query EF and return simple DTOs fit for VM.

This is what CQRS is really about: don't try to fit different responsibilities (write and read) in a single model.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top