MVC + 3 уровня; где ViewModels вступают в игру?

11

Я разрабатываю трехуровневое приложение с использованием ASP.NET MVC 4. В качестве справки я использовал следующие ресурсы.

У меня есть следующий дизайн.

Уровень представления (PL) (основной проект MVC, где M of MVC был перемещен на уровень доступа к данным):

MyProjectName.Main
    Views/
    Controllers/
    ...

Уровень бизнес-логики (BLL) :

MyProjectName.BLL
    ViewModels/
    ProjectServices/
    ...

Уровень доступа к данным (DAL) :

MyProjectName.DAL
    Models/
    Repositories.EF/
    Repositories.Dapper/
    ...

Теперь PL ссылки BLL и BLL ссылки DAL. Таким образом, нижний слой не зависит от того, что над ним.

В этой конструкции PL вызывает службу BLL. PL может передать модель представления в BLL, а BLL может передать модель просмотра обратно в PL.

Кроме того, BLL вызывает уровень DAL, а уровень DAL может возвращать модель обратно в BLL. В свою очередь, BLL может построить модель представления и вернуть ее в PL.

До сих пор этот шаблон работал на меня. Однако я столкнулся с проблемой, когда некоторые из моих моделей ViewModel требуют объединения нескольких объектов. В простом подходе MVC в контроллере я использовал запрос LINQ для выполнения joins, а затем select new MyViewModel(){ ... }. Но теперь, в DAL, у меня нет доступа к тому, где определены ViewModels (в BLL).

Это означает, что я не могу делать соединения в DAL и возвращать их в BLL. Кажется, мне нужно делать отдельные запросы в DAL (вместо соединений в одном запросе), а затем BLL будет использовать их результат для построения ViewModel. Это очень неудобно, но я не думаю, что мне следует открывать DAL для ViewModels.

Любые идеи, как я могу решить эту дилемму? Спасибо.

кочевник
источник

Ответы:

18

основной проект MVC, где M MVC был перемещен на уровень доступа к данным

Распространенное заблуждение. The Mof не MVCимеет ничего общего с данными, несмотря на множество примеров и учебных пособий, которые утверждают, что так.

M это ваша ViewModel и должна находиться в вашем проекте MVC. ViewModels, которые есть в вашем BLL, на самом деле должны называться DataContracts или BusinessModels.

В вашем контроллере у вас есть что-то похожее на это:

Get(id):
    dataContract = _service.Get(id);
    viewModel = Map(dataContract);
    return viewModel

К вашим услугам что-то вроде этого:

Get(id):
    dataModel = _dataAccess.Get(id);
    dataContract = Map(dataModel);
    return dataContract;

А в DataAccess вы выполняете правильные объединения в соответствии с запрошенным объектом. Однако вы, конечно, можете добавлять собственные методы в свой DataAccess при необходимости, чтобы ваша служба могла вызывать эти методы:

GetWithBars():
    dataModels = _repository.Query("select from foos join bars");
    return dataModels;
CodeCaster
источник