Nelle mie applicazioni ho sempre separato le cose, con diversi modelli per il database (Entity Framework) e MVC. Li ho separati anche in diversi progetti:
-
Esempio.Entità : contiene le mie entità per EF e il contesto DB per accedervi.
-
Example.Models - contiene modelli MVC.
-
Example.Web - applicazione web. Dipende da Example.Domain e Example.Models.
Invece di conservare riferimenti ad altri oggetti come fanno le entità di dominio, i modelli MVC conservano gli ID come numeri interi.
Quando arriva una richiesta GET per una pagina, il controller MVC esegue la query del database, che restituisce un'entità. Ho scritto i metodi "Convertitore" che accettano un'entità di dominio e la convertono in un modello MVC. Esistono altri metodi che fanno l'opposto (da un modello MVC a un'entità di dominio). Il modello viene quindi passato alla vista e quindi al client.
Quando arriva una richiesta POST, il controller MVC ottiene un modello MVC. Un metodo di conversione lo converte in un'entità di dominio. Questo metodo esegue anche eventuali convalide che non possono essere espresse come attributi e si assicura che se l'entità di dominio esiste già che la stiamo aggiornando piuttosto che ottenerne una nuova. I metodi di solito assomigliano a questo:
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 questi metodi prendo la duplicazione che altrimenti accadrebbe in ogni controller. L'uso di generici può deduplicare ulteriormente le cose.
Il fare cose in questo modo offre molteplici vantaggi:
- È possibile personalizzare un modello per una vista o un'azione specifica. Supponiamo che tu abbia un modulo di iscrizione per una persona che, una volta inviata, crei molte entità diverse (persona, organizzazione, indirizzo). Senza modelli MVC separati questo sarà molto difficile.
- Se devo passare più informazioni alla vista che altrimenti sarebbero disponibili solo nell'entità, o combinare due entità in un singolo modello, i miei preziosi modelli di database non vengono mai toccati.
- Se serializzi un modello MVC come JSON o XML, ottieni solo il modello immediato serializzato, non tutte le altre entità collegate a questa.