En mis aplicaciones siempre he separado las cosas, con diferentes modelos para la base de datos (Entity Framework) y MVC. También los he separado en diferentes proyectos:
- Ejemplo : Entidades: contiene mis entidades para EF y el contexto de DB para acceder a ellas.
- Ejemplo.Modelos : contiene modelos MVC.
- Ejemplo.Web - aplicación web. Depende tanto de Example.Domain como Example.Models.
En lugar de contener referencias a otros objetos como lo hacen las entidades de dominio, los modelos MVC contienen ID como enteros.
Cuando entra una solicitud GET para una página, el controlador MVC realiza la consulta de la base de datos, que devuelve una entidad. He escrito métodos "convertidores" que toman una entidad de dominio y la convierten en un modelo MVC. Hay otros métodos que hacen lo contrario (de un modelo MVC a una entidad de dominio). El modelo se pasa a la vista y, por lo tanto, al cliente.
Cuando llega una solicitud POST, el controlador MVC obtiene un modelo MVC. Un método convertidor convierte esto en una entidad de dominio. Este método también realiza cualquier validación que no pueda expresarse como atributos, y asegura que si la entidad de dominio ya existe, la estamos actualizando en lugar de obtener una nueva. Los métodos generalmente se ven así:
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;
}
}
Al usar estos métodos, elimino la duplicación que de lo contrario ocurriría en cada controlador. El uso de genéricos puede deduplicar las cosas aún más.
Hacer las cosas de esta manera proporciona múltiples beneficios:
- Puede personalizar un modelo para una vista o acción específica. Supongamos que tiene un formulario de registro para una persona que, cuando se envía, crea muchas entidades diferentes (persona, organización, dirección). Sin modelos MVC separados, esto será muy difícil.
- Si necesito pasar más información a la vista de la que estaría disponible solo en la entidad, o combinar dos entidades en un solo modelo, entonces mis preciosos modelos de bases de datos nunca se tocan.
- Si alguna vez serializa un modelo MVC como JSON o XML, solo obtendrá el modelo inmediato que se serializa, no todas las demás entidades vinculadas a este.