Это плохо для картографа для получения данных из БД?

Я задаюсь вопросом: насколько сложной может быть абстракция картографа?

Допустим, у меня есть действие контроллера

ActionResult Find(QueryInputModel query)

с моделью выглядит так

class QueryInputModel
{
    public string Text {get;set;}
    public IEnumerable<string> RegionCodes {get;set;}
}

Помимо всего прочего, действие превращает входную модель в модель представления.

class QueryViewModel
{
    public string Text {get;set;}
    public IEnumerable<Region> Regions {get;set;}
}

class Region
{
    public string Name {get;set;}
    public string Code {get;set;}
}

где имена регионов в модели представления должны быть взяты из базы данных с использованием кодов во входной модели. Прямо сейчас это сделано QueryMapper.Map(src) метод, который выглядит так

public QueryViewModel Map(QueryInputModel source)
{
    var regions = regionRepository.Get(source.RegionCodes);
    var result = new QueryViewModel {Text=source.Text, Regions=regions};
}

Правильно ли называть такую ​​абстракцию Mapper? Можно ли смешивать прямое отображение и запросы к базе данных в одном методе?

2 ответа

Ну, вот мой взгляд на это. Исходя из того, что вы говорите, у вас есть сценарий использования "Найти детали региона из кодов регионов". Этот вариант использования имеет два входных порта и один выходной порт:

  • Пользователь может ввести свой запрос через один входной порт.
  • Отображение в БД из кодов регионов в детали региона - это еще один входной порт.
  • Способ вернуть результаты пользователю - это выходной порт.

Вся логика, которую вы реализовали в своем Map функция - это логика вашего варианта использования. Функция должна действительно выглядеть следующим образом.

public void FindRegionDetailsFromRegionCodes(IUserQuery userQuery,
                                             IRegionMapper regionMapper,
                                             IUserDisplay userResult) {
    var regions = regionMapper.Get(userQuery.RegionCodes);
    userResult.ShowResult(regions);
}

С:

interface IUserQuery {
  IEnumerable<string> RegionCodes { get; }
}

interface IRegionMapper {
  IEnumerable<Region> Get(IEnumerable<string> regionCodes);
}

interface IUserDisplay {
  void ShowResult(IEnumerable<Region> regions);
}

Таким образом, код варианта использования касается только логики выполнения действия, а не деталей того, как выполняется каждая из этих вещей. Вы можете выставить свой сервис через сетевой порт TCP (путем соответствующей реализации IUserQuery а также IUserDisplay), или рассчитать детали, бросив пару D20 и поиск случайного файла на C:\ и разведение хомяков (путем надлежащего осуществления IRegionMapper).

Теперь правда в том, что вы выставляете этот вариант использования в действии контроллера? Хорошо. Поэтому действие вашего контроллера может вызвать FindRegionDetailsFromRegionCodes передавая это:

  • Ваш QueryInputModel, осуществляя IUserQuery
  • Ваш QueryViewModel, осуществляя IUserDisplay
  • Ваш RegionRepository (Я полагаю, это имя класса), реализуя IRegionMapper

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

Надеюсь это поможет. Чтобы ответить на ваш вопрос, настоящее отображение происходит в БД, поэтому я назвал только порт "БД" IRegionMapper,

Ваше отображение между ViewModel и DataModel является ручным отображением, попробуйте использовать стороннее отображение предпочтений, такое как Automapper или Valueinjecter, оба также могут быть установлены Nuget в ваш файл проекта. Лично предпочитаю Valueinjecter, так как его легче кодировать и понимать.

Другие вопросы по тегам