Nos meus aplicativos, sempre separei as coisas, com modelos diferentes para o banco de dados (Entity Framework) e MVC. Separei-os em diferentes projetos também:
- Example.Entities - contém minhas entidades para EF e o contexto do DB para acessá-las.
- Example.Models - contém modelos MVC.
- Example.Web - aplicativo da web. Depende de Example.Domain e Example.Models.
Em vez de manter referências a outros objetos, como as entidades do domínio, os modelos MVC mantêm os IDs como números inteiros.
Quando uma solicitação GET para uma página chega, o controlador MVC executa a consulta ao banco de dados, que retorna uma entidade. Eu escrevi métodos "Conversor" que pegam uma entidade de domínio e a convertem em um modelo MVC. Existem outros métodos que fazem o oposto (de um modelo MVC para uma entidade de domínio). O modelo é passado para a visualização e, portanto, para o cliente.
Quando uma solicitação POST é recebida, o controlador MVC obtém um modelo MVC. Um método conversor converte isso em uma entidade de domínio. Esse método também executa validações que não podem ser expressas como atributos e garante que, se a entidade do domínio já existir, estamos atualizando-a em vez de obter uma nova. Os métodos geralmente se parecem com isso:
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;
}
}
Usando esses métodos, retiro a duplicação que, de outra forma, ocorreria em cada controlador. O uso de genéricos pode deduplicar as coisas ainda mais.
Fazer as coisas dessa maneira fornece vários benefícios:
- Você pode personalizar um modelo para uma exibição ou ação específica. Digamos que você tenha um formulário de inscrição para uma pessoa que, quando enviada, cria muitas entidades diferentes (pessoa, organização, endereço). Sem modelos separados de MVC, isso será muito difícil.
- Se eu precisar passar mais informações para a visualização do que estaria disponível apenas na entidade ou combinar duas entidades em um único modelo, meus preciosos modelos de banco de dados nunca serão tocados.
- Se você serializar um modelo MVC como JSON ou XML, apenas o modelo imediato será serializado, e nem todas as outras entidades vinculadas a este.