W moich aplikacjach zawsze rozdzielałem różne rzeczy dla różnych baz danych (Entity Framework) i MVC. Podzieliłem je również na różne projekty:
- Example.Entities - zawiera moje byty dla EF i kontekst DB dla dostępu do nich.
- Przykład Modele - zawiera modele MVC.
- Example.Web - aplikacja internetowa. Zależy zarówno od Example.Domain, jak i Example.Models.
Zamiast przechowywania odniesień do innych obiektów, takich jak jednostki domeny, modele MVC przechowują identyfikatory jako liczby całkowite.
Kiedy przychodzi żądanie GET dla strony, kontroler MVC wykonuje zapytanie do bazy danych, które zwraca jednostkę. Napisałem metody „konwertera”, które pobierają jednostkę domeny i przekształcają ją w model MVC. Istnieją inne metody, które działają odwrotnie (od modelu MVC do encji domeny). Model zostaje następnie przekazany do widoku, a tym samym do klienta.
Kiedy przychodzi żądanie POST, kontroler MVC otrzymuje model MVC. Metoda konwertera konwertuje to na jednostkę domeny. Ta metoda wykonuje również wszelkie weryfikacje, których nie można wyrazić jako atrybuty, i upewnia się, że jeśli jednostka domeny już istnieje, to ją aktualizujemy, a nie otrzymujemy nową. Metody zwykle wyglądają mniej więcej tak:
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;
}
}
Korzystając z tych metod, usuwam duplikację, która w innym przypadku wystąpiłaby w każdym kontrolerze. Zastosowanie generycznych może jeszcze bardziej zduplikować rzeczy.
Robienie rzeczy w ten sposób zapewnia wiele korzyści:
- Możesz dostosować model do konkretnego widoku lub akcji. Załóżmy, że masz formularz rejestracyjny dla osoby, która po przesłaniu tworzy wiele różnych podmiotów (osoba, organizacja, adres). Bez osobnych modeli MVC będzie to bardzo trudne.
- Jeśli muszę przekazać do widoku więcej informacji, niż byłoby to dostępne tylko w encji, lub połączyć dwie encje w jeden model, moje cenne modele baz danych nigdy nie zostaną zmienione.
- Jeśli kiedykolwiek serializujesz model MVC jako JSON lub XML, otrzymasz tylko natychmiastowy serializowany model, a nie wszystkie inne podmioty powiązane z tym modelem.