У меня есть веб-решение (в VS2010) с двумя подпроектами:
Domain
, которое содержит классы Model
(сопоставленные с таблицами базы данных через Entity Framework) иServices
, который (помимо прочего) отвечает за операции CRUD
WebUI
, который ссылается на проект домена
Для первых страницЯ создал, что использовал классы Model из проекта Domain непосредственно в качестве Model в моих строго типизированных представлениях, потому что классы были небольшими, и я хотел отобразить и изменить все свойства.
ТеперьУ меня есть страница, которая должна работать только с небольшой частью всех свойств соответствующей доменной модели.Я получаю эти свойства, используя проекцию результата запроса в моем классе Service.Но мне нужно проецировать в тип - и вот мои вопросы о решениях, которые я могу придумать:
Я представляю ViewModels
, которые живут в WebUI
проецируйте и выставьте IQueryables
и EF data context
из сервиса в проект WebUI.Затем я могу напрямую проецировать в эти ViewModels.
Если я не хочу показывать IQueryables и контекст данных EF, я помещаю классы ViewModel
в проект Domain
, затемЯ могу вернуть ViewModels напрямую в результате запросов и проекций классов Service.
В дополнение к ViewModels
в проекте WebUI
я представляю Data transfer objects
, которые перемещаютсяданные из запросов в классах обслуживания в ViewModels
.
решения 1 и 2 выглядят одинаково, и я склонен предпочесть решение 2, чтобы сохранить всеБаза данных относится к отдельному проекту.Но почему-то звучит неправильно иметь View -Models в проекте Domain.
Решение 3 звучит как гораздо больше работы, так как у меня есть больше классов для создания и заботы о Model-DTO-Модель ViewView.Я также не понимаю, в чем разница между DTO и ViewModels.Разве ViewModels - это не коллекция выбранных свойств моего класса Model, которые я хочу отобразить?Разве они не будут содержать тех же членов, что и DTO?Почему я хотел бы проводить различие между ViewModels и DTO?
Какое из этих трех решений предпочтительнее и каковы преимущества и недостатки?Есть ли другие варианты?
Спасибо за отзыв заранее!
Редактировать (потому что у меня, возможно, была слишком длинная стена текста и меня попросили ввести код)
Пример: у меня есть Customer
Entity ...
public class Customer
{
public int ID { get; set; }
public string Name { get; set; }
public City { get; set; }
// ... and many more properties
}
... и я хочу создать вид, который показывает только (и, возможно, позволяет редактировать) Name
изклиенты в списке.В классе Service я извлекаю данные, необходимые для просмотра, с помощью проекции:
public class CustomerService
{
public List<SomeClass1> GetCustomerNameList()
{
using (var dbContext = new MyDbContext())
{
return dbContext.Customers
.Select(c => new SomeClass1
{
ID = c.ID,
Name = c.Name
})
.ToList();
}
}
}
Затем существует CustomerController с методом действия.Как это должно выглядеть?
Либо так (а) ...
public ActionResult Index()
{
List<SomeClass1> list = _service.GetCustomerNameList();
return View(list);
}
... или лучше так (б):
public ActionResult Index()
{
List<SomeClass1> list = _service.GetCustomerNameList();
List<SomeClass2> newList = CreateNewList(list);
return View(newList);
}
Что касается варианта 3 выше, я бы сказал: SomeClass1
(живет в Domain
проекте) - это DTO , а SomeClass2
(живет в WebUI
проекте) - ViewModel .
Мне интересно, имеет ли смысл когда-нибудь различать два класса.Почему бы мне не всегда выбирать опцию (а) для действия контроллера (потому что это проще)?Есть ли причины для введения ViewModel (SomeClass2
) в дополнение к DTO (SomeClass1
)?