Доступ к данным осуществляется с использованием архитектуры, состоящей из трех слоев.
DAL – Data Access Layer. Это классы репозиториев. Репозитории должны содержать либо атомарные операции, такие как
- FindById()
- Add()
- Update()
- Delete()
- SaveChanges()
- либо операции, возвращающие IQueryable.
На этом уровне нет смысла возвращать List из всех строк таблицы базы, т.к. почти наверняка на следующем уровне эта коллекция будет либо отфильтрована, либо отсортирована, а эти операции лучше выполнять на стороне базы данных.
BLL – Business layer. Это классы менеджеров. Каждый класс менеджера содержит в себе один или несколько классов репозитория. Методы менеджеров либо просто вызывают атомарные операции репозиториев, либо накладывают дополнительные условия на методы, возвращающие IQueryable, и возвращают готовый список. Все логика по фильтрации, сортировке, загрузке navigation properties и т.д. должна выполняться именно на этом уровне. Если необходимо получить по разному сформированные коллекции, то надо смотреть, насколько различаются способы их получения, и выбирать – либо получать их с помощью одного и того же метода с разными параметрами, либо реализовать несколько разных методов.
Слой контроллеров. На этом уровне должны быть только вызовы методов менеджеров и формирование модели для View. Вся логика должны быть реализована на уровне менеджеров. При этом если предполагается, что сущность в одном Action будет меняться несколько раз, нет необходимости сохранять ее после каждого сохранения. Гораздо эффективнее будет вначале сделать все изменения в памяти, а потом сохранить их в базу одним вызовом SaveChanges.
О чем говорится в последнем абзаце. Допустим, есть несколько сложных операций, которые надо сделать с сущностью базы данных. Допустим, для каждой из этих операций мы реализуем отдельный метод в менеджере.
void UpdateProperties1(Entity entity, Model model)
{
//some logic
Update(entity)
}
void UpdateProperties2(Entity entity, Model model){ … }
Допустим, в каждом из этих методов в конце будет вызван метод SaveChanges или Update. При этом, если в контроллере они будут вызваны один за другим, каждое изменение сущности будет сохраняться в базу отдельным запросом.
Гораздо эффективнее сделать дополнительный метод вида
void SaveChanges();
и вызывать этот метод в контроллере после завершения всех манипуляций с данными. Например:
UpdateProperties1(entity, model);
UpdateProperties2(entity, model);
SaveChanges();
Периодически мы проводим обучение и даем возможность стажировки на базе нашей платформы с управлением на SQL. Если вам это интересно, то пожалуйста посмотрите информацию об обучении/стажировке по SQL.
CRM и сайт компании в одном флаконе.
Личные кабинеты для клиентов и сотрудников вашей компании.