Доступ к данным осуществляется с использованием архитектуры, состоящей из трех слоев.
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.

Опубликовано в ASP.NET