MVC3 best practices to save view with multiple entities - asp.net-mvc-3

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!

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.

Related

Migrating complex core data model

I have a couple of questions about core data model migration.
I have a pretty complex data model with a couple cases of entity inheritance. I was going to make some changes to the data model in a new version and try and setup migration but when it migrated the store I lost some of the data that belonged to an entity that inherited from another entity.
In my case I have a few entities that all inherit from a "Resource" entity. This resource entity has a attribute "name". When I try to migrate the data store all entities that inherit from the "Resource" entity lose their name.
Is their any way to get model migration working for a data model with inheritance? I have already shipped a beta and I need to make a couple of updates to the model but I obviously don't want the users to lose all of their data.
Thanks
Try "playing" on your new model with Column properties > Versioning > Renaming identier, entering the previous field name, which I guess is the same. I doubt that will work with inheritance, but that is worth the try... (That not so documented feature, allowing to keep data across renames, saved me several times).
If that doesn't work, I'm afraid you have to do a "manual migration"... with Model mappings and other things... which is imho a bit complex. See Apple documentation on this topic... I then would suggest to just rollback your changes and forget inheritance, quicker & easier, even if it is less "clean". Or just assume your users will loose some data, at beta stage this is not so important... (Or maybe you can just collect old data in memory/plist file before migrating model an then repopulate)
Good luck! CoreData automatic model migration is great, but take care that it will work only with simple modifications...
Oh, just one another trick, add -com.apple.CoreData.SQLDebug 1 to your app launch arguments, and you will get all sql requests generated by CoreData... That might help you to understand the migration process. (and some other things...)

Should i create the model classes based on the structure of data in Database?

I have predefined tables in the database based on which I have to develop a web application.
Should I base my model classes on the structure of data in the tables.
But a problem is that the tables are very poorly defined and there is much redundant data in them (which I can not change!).
Eg. in 2 tables three columns are same.
Table: Student_details
Student_id , Name, AGe, Class ,School
Table :Student_address
Student_id,Name,Age, Street1,Street2,City
I think you should make your models in a way that would be best suited for how they will be used. Don't worry about how the data is stored or where it is stored... otherwise why go through the trouble of layering your code. Why not just do the direct DB query right in your view? So if you are going to create an abstraction of your data... "model" ... make one that is designed around how it will be used... not how it will be or is persisted.
This seems like a risky project - presumably, there's another application somewhere which populates these tables. As the data model is not very sound from a relational point of view, I'm guessing there's a bunch of business/data logic glued into that app - for instance, putting the student age into the StudentAddress table.
I'd support jsobo in recommending you build your business logic independently of the underlying persistance mechanism, and that you try to keep your models as domain focused as possible, without too much emphasis on how the database happens to be structured.
You should, however, plan on spending a certain amount of time translating your domain models into their respective data representations and dealing with whatever quirks the data model imposes. I'd strongly recommend containing all this stuff in a separate translation layer - don't litter it throughout the rest of the application.

UI-centric vs domain-centric data model - pros and cons

How closely does your data model map to your UI and domain model?
The data model can be quite close to the domain model if it has, for example, a Customer table, an Employee table etc.
The UI might not reflect the data model so closely though - for example, there may be multiple forms, all feeding in bits-and-pieces of Customer data along with other miscellaneous bits of data. In this case, one could you have separate tables to hold the data from each form. As required the data can then combined at a future point... Alternatively one could insert the form data directly into a Customer table, so that the data model does not correlate well to the UI.
What has proven to work better for you?
I find it cleaner to map your domain model to the real world problem you are trying to solve.
You can then create viewmodels which act as a bucket of all the data required by your view.
as stated, your UI can change frequently, but this does not usually change the particular domain problem you are tackling...
information can be found on this pattern here:
http://blogs.msdn.com/dphill/archive/2009/01/31/the-viewmodel-pattern.aspx
UI can change according to many needs, so it's generally better to keep data in a domain model, abstracted away from any one UI.
If I have a RESTful service layer, what they are exposing the domain model. In that case , the UI(any particular screen) calls a number of these services and from the domain models collected composes the screen. In this scenario although domain models bubble all the way up to UI the UI layer skims out the necessary data to build its particular screen. There are also some interesting questions on SO about on using domain model(annotated) for persistence.
My point here is the domain models can be a single source of truth. It can do the work of carrying data , encapsulating logic fairly well. I have worked on projects which had a lot of boilerplate code translating each domain model to DTO, VO , DO and what-have-yous. A lot of that looked quite unnecessary and more due to habit in most cases.

Mapping Linq Entities and Domain Objects and object tracking

If I map my Domain objects to linq Entities will I now not be able to track changes when saving my domain objects? So for any change in my model that i wish to make, once I map the object to linq entities for submission to db, all object values will be submitted to the db by linq since it it goes through a mapping first? Or would the object tracking here still be utilized?
Depends on the O/R mapper you're using. You're referring to entity framework which doesn't do any change tracking inside the entity and therefore it needs help from you when you re-attach an entity which previously was fetched from the db (so it knows it's not new).
Here's an article from microsoft about CRUD operations in multi-tiered environments (similiar issues to your Domain mapping scenario).
Check out the Update - With Complete Entities for the way to do change tracking yourself.
There's another technique, where you attach the entity as unmodified, and then .Refresh() with Keep Current Values - replacing the original. This would allow you to Insert/Update/Do Nothing as appropriate at the cost of a database roundtrip.

In MVC, does an ORM represent the model?

In MVC, is the ORM the same as the model or just a way the model can be designed? In other words, the "model" doesn't care how you get data as long as you get it. Or, does "model" imply that I no longer have a bunch of SQL statements in my code like in code behind forms? Something else?
Thank you.
No, the ORM is the thing that maps a code-based model to your database and vice versa.
For basic CRUD apps, where your model in code is literally just DTOs that represent the database and you're loading, editing, and saving them, that's how you'd use it. If you do have a "proper" Domain Model, then it's a bit more complex because ideally you'd want to decouple the shape of the Domain Model classes from the shape of the database tables.
To elaborate, you would create your model in your code to represent the Domain Model (i.e. the various elements of your problem domain), build some sort of "memento" classes that are pure DTOs that you can convert your Domain Model classes from/into. Then configure an ORM (object relational mapper) to map those memento DTOs to a database. I.e. Generate SQL statements that will update the database based on the model objects you give to it.
I can understand some confusion, because there are tools (LINQ to SQL being one) that actually generate model classes in a designer for you. This isn't pure ORM, like NHibernate, where you provide the ORM plain old objects and some mapping configuration that it uses (often in conjunction with reflection) to automatically generate the SQL statements for the database. You could possibly get away with using EF Code First to map a Domain Model directly to the database, but I think in the end it may get messy as you try to make changes to one or the other.
If you'd like to have a look at a good real world implementation of MVC with an ORM, have a look at S#arp Architecture which is based on MS ASP.NET MVC, Nhibernate and the repository pattern.
The model should be decoupled from the backend data store technology as much as possible.
I thought this was a pretty good article that discusses the relationship between data access layers, DTOs, etc. http://msdn.microsoft.com/en-us/magazine/dd263098.aspx

Resources