АСП. NET MVC: сопоставление сущностей с моделью представления

Я пытаюсь очистить свои методы действий в проекте ASP.NET MVC, используя модели представлений. В настоящее время мои модели представления содержат сущности, которые могут иметь отношения с другими сущностями. Например, класс ContactViewModel может иметь контакт, который может иметь адрес, оба из которых являются отдельными объектами. Чтобы запросить список объектов Contact, я мог бы сделать что-то вроде следующего.

IList<Contact> contacts;

using (IContactRepository repository = new ContactRepository())
{
    contacts = repository.Fetch().ToList();
}

EditContactViewModel vm = new EditContactViewModel(contacts);

return View(vm);

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

Я рассматривал возможность создания расширенного класса, содержащего свойства объектов Contact и Address. Затем я мог спроецировать объекты Contact и Address в свой новый плоский объект. Одна из моих проблем с этим подходом заключается в том, что мои методы действий могут быть немного заняты, и я не думаю, что AutoMapper может отображать два или более объекта в один тип.

Какие методы предпочтительны для преодоления моих опасений?


person senfo    schedule 15.02.2010    source источник


Ответы (2)


Automapper будет работать для вашего случая. У вас есть граф объектов, у вещи есть еще несколько вещей, с которыми Automapper отлично справляется.

person John Farrell    schedule 15.02.2010
comment
Очень круто. Я все еще новичок в AutoMapper, поэтому я даже не знал, что он может вот так отображать. Большое Вам спасибо. - person senfo; 16.02.2010

Принимая эти опасения по порядку...

Во-первых, если вы беспокоитесь об использовании инструкции и репозитория (я не знаю, является ли это LINQ-to-SQL или LINQ-to-Entities, но это не имеет значения), я бы рекомендовал вам реализовать IDisposable на вашем контроллере, а затем сохраните репозиторий в поле либо в модели, либо в контроллере, либо где-нибудь, где у вас есть доступ к нему в представлении (если вам это нужно, если модель знает об этом, пока объект находится " живым», тогда вам просто нужно сохранить его на протяжении всего срока службы контроллера).

Затем, когда запрос выполнен, вызывается метод Dispose на вашем контроллере, и вы можете избавиться от репозитория там.

Лично у меня есть метод в моем базовом классе контроллера, который выглядит так:

protected T AddDisposable<T>(T disposable) where T : class, IDisposable
{
    // Error checking.
    if (disposable == null) throw new ArgumentNullException("disposable");

    // Add to list
    ...
}

По сути, он позволяет хранить реализации IDisposable, а затем в реализации контроллера IDisposable он выполняет итерацию по списку, избавляясь от всего.

Что касается раскрытия адреса в модели объекта, лично я не вижу в этом проблемы с кровотечением. Адрес является частью состава контакта (ИМО), поэтому было бы неправильно отсутствовать его там.

Тем не менее, я не возражаю, если вы не хотите, чтобы он был там, потому что вы хотите сосредоточиться на одном типе в одном контроллере за раз и т. д. и т. д.

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

person casperOne    schedule 15.02.2010