MVC2 путаница по поводу того, когда использовать viewmodels или доменные объекты - PullRequest
0 голосов
/ 22 июня 2011

После ознакомления с учебником Steve Sandersons pro asp.net Framework мне удалось получить базовые функции редактирования и отображения для двух объектов базы данных с использованием шаблона репозитория.

У меня проблемы, когда я хочу отобразить / обновить свойства из нескольких объектов.

Мне известно, что viewmodels - это способ сделать это, но я не совсем понимаю, когда мне следует использовать viewmodel и как они вписываются в мои объекты модели предметной области.

Например, для моих двух объектов у меня есть репозиторий и следующие методы для возврата каждого списка объектов

public IQueryable<Customer> Customers
    {
        get { return customersTable; }
    } 

public IQueryable<CustomerSite> CustomerSites
    {
        get { return customerSitesTable; }
    }

Затем в моем контроллере я передаю объекты из репозитория в представление как

 public ViewResult List([DefaultValue(1)] int page)
    {
        var customerSitesToShow = customerSiteRepository.CustomerSites;
        var customersToShow = customerRepository.Customers; 
        var viewModel = new CustomerSitesListViewModel
        {

            CustomerSites = customerSitesToShow.Skip((page - 1) *  PageSize).Take(PageSize).ToList(),
            customers = customersToShow.Skip((page - 1) * PageSize).Take(PageSize).ToList(),

            PagingInfo = new PagingInfo
            {
                CurrentPage = page,
                ItemsPerPage = PageSize,
                TotalItems = customerSitesToShow.Count()
            }
        };

        return View(viewModel);  //Passed to view as ViewData.Model (or simply model)
    }

}

Теперь я понимаю, что могу использовать модель представления для доступа к свойствам двух объектов в одном представлении, поэтому у меня есть одна модель представления со свойствами для моих двух объектов

{
public class SiteViewModel
{
    public int Id { get; set; }
    public int CustomerId { get; set; }
    public string AddressLine1 { get; set; }
}

public class CustomerViewModel
{
    public int Id { get; set; }
    public string CustomerName { get; set; }
    public string PrimaryContactName { get; set; }
    public SiteViewModel Site { get; set; }
}

}

Затем мастер-представлениемодель, которую я строго ввожу в шаблон отображения

public class CustomerSitesListViewModel
{
    public IList<CustomerSite> CustomerSites { get; set; }
    public PagingInfo PagingInfo { get; set; }
    public IList<Customer> customers { get; set; }
    public CustomerViewModel Customers { get; set; }
}

Когда я запускаю это, шаблон отображения отображается, но моя коллекция клиентов пуста, так как я думаю, что мне нужен оператор соединения LINQ для получения списка клиентов исайты клиентов?Является ли LINQ join лучшим способом сделать это?так что я могу получить доступ к обоим объектам из шаблона отображения, например

<%= Html.DisplayFor(x => x.Customers.CustomerName) %>
<%= Html.DisplayFor(x => x.Customers.Site.AddressLine1) %>

. Здесь я запутываюсь, когда должен идти метод, содержащий запрос LINQ, чтобы вернуть коллекцию клиентов, если это должно быть в хранилищеили вид модели?

1 Ответ

0 голосов
/ 23 июня 2011

Насколько я понимаю, вы путаете две разные обязанности, которые имеют доменные объекты и одну из модели представления.

Я не очень хорошо вижу вашу модель. У клиента есть один сайт или более? Каковы отношения между ними? С моей точки зрения, что вы можете сделать на уровне хранилища, сделайте это на этом уровне. Поэтому я бы вернул Заказчика с его Сайтом непосредственно из хранилища, поскольку вы можете объединять данные на уровне хранилища с помощью объединений и возвращать их за один прием в базу данных.

Зачем беспокоиться о возврате двух отдельных лиц: Customer и CustomerSite, поскольку вы знаете, что они необходимы в соответствии с вашими взглядами? Вы создаете больше проблем, чем необходимо.

Таким образом, возврат Customer и Site из хранилища за один раз может быть после сопоставления с объектом модели плоского представления, например с именем CustomerWithSite. Для этого вы можете использовать AutoMapper (http://automapper.codeplex.com/).. У вас также может быть «специальный» репозиторий для представлений, который уже возвращает объект, отформатированный для представления, являющегося результатом запросов и проекций в хранилище. Это ваше дело. Но не используйте ваш доменный объект для представления .

Я бы также не выставлял IQueryable вне моего репозитория. Вы попадете в беду. Поскольку однажды вы разрешаете другим слоям манипулировать вашими запросами, репозиторий больше не отвечает за то, что возвращается. Тогда некоторые разработчики будут пытаться манипулировать Iqueryable в представлении, но недостатком является то, что ему необходимо открыть соединение с базой данных. Не очень хороший дизайн с моей точки зрения, чтобы держать связь открытой для этого. Что делать, если соединение было закрыто раньше? Вы получите исключение Disposed при отображении объектов в представлении. Не очень хорошо Подумайте также о тестируемости.

Не знаю, понятнее ли вам, но помните о недостатках, о которых я говорю.

...