In my applications I have always separated things out, with different models for the database (Entity Framework) and MVC. I have separated these out into different projects too:
- Example.Entities - contains my entities for EF and the DB context for accessing them.
- Example.Models - contains MVC models.
- Example.Web - web application. Depends on both Example.Domain and Example.Models.
Instead of holding references to other objects like the domain entities do, the MVC models hold IDs as integers.
When a GET request for a page comes in, the MVC controller performs the database query, which returns an entity. I have written "Converter" methods that take a domain entity and convert it to an MVC model. There are other methods that do the opposite (from an MVC model to a domain entity). The model then gets passed to the view, and thus to the client.
When a POST request comes in, the MVC controller gets an MVC model. A converter method converts this to a domain entity. This method also performs any validations that can't be expressed as attributes, and makes sure that if the domain entity already exists that we are updating it rather than getting a new one. The methods usually look something like this:
public class PersonConverter
{
public MyDatabaseContext _db;
public PersonEntity Convert(PersonModel source)
{
PersonEntity destination = _db.People.Find(source.ID);
if(destination == null)
destination = new PersonEntity();
destination.Name = source.Name;
destination.Organisation = _db.Organisations.Find(source.OrganisationID);
//etc
return destination;
}
public PersonModel Convert(PersonEntity source)
{
PersonModel destination = new PersonModel()
{
Name = source.Name,
OrganisationID = source.Organisation.ID,
//etc
};
return destination;
}
}
By using these methods I take the duplication out that would otherwise occur in each controller. The use of generics can deduplicate things even further.
Doing things this way provides multiple benefits:
- You can customise a model to a specific view or action. Say you have a signup form for a person that when submitted, creates many different entities (person, organisation, address). Without seperate MVC models this will be very difficult.
- If I need to pass more information to the view than would otherwise be available just in the entity, or combine two entities into a single model, then my precious database models are never touched.
- If you ever serialise an MVC model as JSON or XML, you only get the immediate model being serialised, not every other entity linked to this one.