Где я должен выполнить запрос с помощью ToList() — в DAL, BLL или в контроллере?

#asp.net-mvc #n-tier-architecture

#asp.net-mvc #n-уровневая архитектура

Вопрос:

У меня есть проекты DAL, BLL и Web. Где я должен выполнить запрос с помощью ToList()?

Прямо сейчас я выполняю запрос с помощью ToList () в контроллере — это нормально? Например — с самого начала:

DAL — мой метод в классе NotesRepository:

 public IQueryable<Notes> GetAllNotes()
{
    return context.Notes.Include(x => x.Comments).OrderByDescending(x => x.CreateDate);
}
  

BLL — мой метод в классе NotesService:

 public IEnumerable<Notes> GetNotes()
{
    return _unitOfWork.NotesRepository.GetAllNotes();
}
  

Веб — мое действие в контроллере (выполнение запроса с использованием ToList()):

 public ActionResult Index()
{
    var notes = _notesService.GetNotes().ToList();

    return View(notes);
}
  

Ответ №1:

По моему личному мнению, это проблема с данными, поэтому решение о вызове.ToList() должно произойти в DAL. Может быть, нужно использовать гибкость, чтобы, возможно, связать вещи вместе или уточнить запрос, чтобы вы могли оправдать размещение вызова в BLL, но вы все равно встраиваете эту гибкость в DAL, и в целом DAL возвращает данные, а не объекты запроса.

Не то чтобы это когда-либо происходило в реальной жизни, но это также дает вам больше гибкости при замене DAL на какой-либо другой источник данных (например, веб-API). Если вы вводите IQueryable в свой DAL, это усложняется, и инкапсуляция уровня / tier нарушается.

Я бы не рекомендовал разрешать IQueryable в контроллере.

Комментарии:

1. спасибо — так что ToList() в DAL и возвращает IEnumerable, а не IQueryable — спасибо 🙂

Ответ №2:

Я согласен с @cadmium, я бы также сделал это в DAL, а не в контроллере.

PS: Я предпочитаю передавать IEnumerable всегда, насколько это возможно, и обрабатывать конкретный список только тогда, когда вам это действительно нужно.

Комментарии:

1. Зачем возвращать IEnumerables, когда это фактически список? Кто-то мог бы сделать другое. ToList(). Я всегда стараюсь требовать наименее специфичных входных данных и возвращать выходные данные как можно более конкретными.

2. @Maarten, в этом примере (с доступом к БД) Я бы передал IEnumerable, потому что вы можете отложить работу до фактического перечисления. Другая причина в том, что IEnumerable<> — это универсальный интерфейс, а List — это фактическая реализация. Предположим, что по какой-то причине вам нужно изменить возвращаемое значение из списка в массив, если тип возвращаемого значения — список, вам нужно изменить эту подпись на Array, и пользователям, которые уже используют этот код, тоже потребуется. Если подпись является перечислимой, вы можете изменить на array, и потребителям не нужно будет ее изменять. Но, как всегда, это зависит от ваших потребностей.