2014-11-23 3 views
0

Я разрабатываю приложение ASP.NET MVC, и я пришел в довольно неловкую ситуацию.ViewModels и модели домена в ASP.NET MVC

У меня есть страница, где пользователь может искать некоторые предметы (скажем, студенты) по некоторым критериям. Я использовал, чтобы передать коллекцию студентов на мой взгляд, но потом я добавил некоторые параметры поиска, поэтому я решил создать ViewModel следующий

public class SearchViewModel 
{ 
    public string SearchString { get; set; } 
    public bool IsCaseSensitive { get; set; } 
    ... 
    //other parameters 
    ... 
    public IEnumerable<Student> Students { get; set; } 
} 

Тогда я думал о ситуации, когда я необходимо добавить дополнительную информацию каждому учащемуся, который не хранится в базе данных и генерируется на контроллере. Моя первая мысль была совершенно идиотской - я добавил дополнительный массив, чтобы сохранить его в ViewModel, как это:

public class SearchViewModel 
{ 
    public string SearchString { get; set; } 
    public bool IsCaseSensitive { get; set; } 
    ... 
    //other parameters 
    ... 
    public IEnumerable<Student> Students { get; set; } 
    public IEnumerable<int> someData { get; set; } 
} 

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

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

public class SearchViewModel 
{ 
    public string SearchString { get; set; } 
    public bool IsCaseSensitive { get; set; } 
    ... 
    //other parameters 
    ... 
    public IEnumerable<StudentViewModel> StudentModels { get; set; } 
} 

public class StudentViewModel 
{ 
    public Student Student { get; set; } 
    public int someData { get; set; } 
} 
  1. Это прекрасная идея для создания таких моделей 'помощников', как StudentViewModel? Я бы, вероятно, не использовал StudentViewModel нигде, кроме внутри SearchViewModel. Учитывая, что SearchViewModel является своеобразной моделью «помощи», создание другой модели, используемой только внутри SearchViewModel, кажется немного странным. Это так?

  2. Насколько я понял, ViewModel никогда не должен содержать модель домена. Должен ли я делить свойство Студент на более мелкие свойства? Например, как это:

    public class StudentViewModel 
    { 
        public string Name { get; set; } 
        public int GroupId { get; set; } 
        public int someData { get; set; } 
    } 
    
  3. В общем, как я понял, модель представления должна состоять только примитивов и их коллекций (и, возможно, другие ViewModels как в первом вопросе). Правильно ли это?

ответ

1

Я не претендую на эту неприкосновенную истину. Но по-моему:

  1. Очень часто модель просмотра создается только для одного вида.
  2. Использование моделей доменов/данных в представлениях обычно (если это упрощает/ускоряет процесс разработки). В вашем случае я бы не стал использовать Student class в ViewModel.
  3. ViewModel должен содержать все данные, необходимые для построения (примитивы, а не примитивы). Но если вы можете сделать модель представления проще и понятнее, выполняя некоторую работу в контроллере, тогда это должно быть сделано.
1
  1. Это прекрасная идея для создания таких моделей «помощников», как StudentViewModel?

Я считаю, что это так. Ваше представление «состоит» из списка «взглядов студентов». Моды просмотра существуют только для обслуживания ваших представлений с данными, которые структурированы оптимальным образом, так что необходимая логика в представлении минимальна.

  1. Насколько я понял, ViewModel никогда не должен содержать модель домена.

Я бы посоветовал не использовать ваши сущности во взглядах, особенно при работе с формами или другими способами ввода данных. В этом случае часто бывает интересно создать специальную «модель формы», которая содержит только те свойства, которые вы хотите отправить своему пользователю. Это также позволяет вам писать логику проверки для этой конкретной формы. Подумайте об этом как о модели, которая служит вашей форме, подобно тому, как модель представления служит вашему представлению. Используйте AutoMapper, чтобы заполнить эти модели форм, чтобы сделать вашу жизнь проще.

Однако в некоторых сценариях я считаю приемлемым использование сущностей в ваших представлениях: когда вы используете EF и ленивую загрузку, вы можете использовать сущности при отображении данных для получения прибыли от ленивого механизма загрузки. Только данные, которые вы показываете, будут загружены из базы данных. Однако, поскольку заранее известно, какие данные вам понадобятся, обычно есть лучшие стратегии загрузки данных. Ложная загрузка удобна во время разработки, когда происходит множество изменений (загрузка &, показывающая дополнительные данные, быстро & проста в использовании без необходимости менять код), но, как правило, это первое, что нужно решать во время обзоров производительности.

  1. Должен ли я делить свойство Студента на более мелкие свойства? В общем, как я понял, ViewModel должен состоять только из примитивов и их коллекций (и, возможно, других ViewModels, как в первом вопросе). Правильно ли это?

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

Это мои 2 цента.

+0

Спасибо. Единственное, что я не совсем понял, это ваш третий ответ. Ссылаясь на ваш второй ответ, я не должен использовать любую модель домена (обычный Student, а не StudentViewModel) в своих представлениях. Тем не менее, тогда вы говорите, что я действительно должен использовать свой класс учеников. Правильно ли я понял, что лучший способ состоит в том, чтобы 1) сохранить модель домена Student как есть и 2) использовать StudentViewModel для нужд представлений вместо того, чтобы делить его на разные свойства? Кроме того, мне не очень нравятся условия DTO. Могут ли мои ViewModels рассматриваться как DTO? –

Смежные вопросы