У своїх програмах я завжди розділяв речі з різними моделями для бази даних (Entity Framework) та MVC. Я також розділив їх на різні проекти:
- Example.Entities - містить мої сутності для EF та контекст БД для доступу до них.
- Example.Models - містить моделі MVC.
- Example.Web - веб-додаток. Залежить і від Example.Domain, і Example.Models.
Замість того, щоб містити посилання на інші об'єкти, як це роблять сутні домени, моделі MVC містять ідентифікатори як цілі числа.
Коли надходить запит GET на сторінку, контролер MVC виконує запит бази даних, який повертає сутність. Я написав методи "Конвертер", які беруть об'єкт домену і перетворюють його в модель MVC. Є й інші методи, які роблять навпаки (від моделі MVC до об'єкта домену). Потім модель передається перегляду, а отже, і клієнту.
Коли надходить запит POST, контролер MVC отримує модель MVC. Метод перетворювача перетворює це в об'єкт домену. Цей метод також виконує будь-які перевірки, які не можуть бути виражені як атрибути, і гарантує, що якщо об'єкт домену вже існує, ми його оновлюємо, а не отримуємо новий. Методи зазвичай виглядають приблизно так:
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;
}
}
Використовуючи ці методи, я виймаю дублювання, яке в іншому випадку відбудеться в кожному контролері. Використання дженерики може ще більше підкреслити речі.
Цей спосіб дає багато переваг:
- Ви можете налаштувати модель під конкретний вигляд або дію. Скажімо, у вас є форма для реєстрації особи, яка при надходженні створює безліч різних організацій (особа, організація, адреса). Без окремих моделей MVC це буде дуже складно.
- Якщо мені потрібно передати більшу інформацію, ніж вона була б доступна лише в об'єкті, або об'єднати два об'єкти в одну модель, то мої дорогоцінні моделі баз даних ніколи не торкаються.
- Якщо ви коли-небудь серіалізуєте модель MVC як JSON або XML, ви отримуєте серіалізацію лише негайної моделі, а не кожну іншу сутність, пов'язану з цією.