Использование принципа разделения команд и запросов в контроллерах MVC

Мне нравится идея разделения командных запросов, но я не вижу, как использовать ее в действии контроллера MVC, который добавляет объект и нуждается в новом идентификаторе объекта после добавления.

Например, в приведенном ниже упрощенном примере служба используется для создания нового элемента:

public ActionResult Assign(AssignViewModel viewModel)
{
     var newItem = _AssignItemService.AssignItem(viewModel.ItemName, viewModel.ItemValue);

     return RedirectToAction("ListItem", new {id = newItem.Id);
}

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

В чистом CQS команда не имеет возвращаемого значения, поэтому приведенный выше шаблон будет недействительным.

Любой совет с благодарностью получен.

3 ответа

Решение

Вы должны перейти к AssignItem Если метод экземпляра "Item" (или какова бы ни была ваша сущность), который создается из значений viewmodel, то метод не должен ничего возвращать, вместо этого он просто обновит свойство Id сущности, сделав его методом Command.

Затем вы можете использовать entity.Id для чего угодно

Я думаю, что вы застряли в педантичной точке.

Запрос - это когда вы хотите задать вопрос базе данных, например: "Сколько клиентов к западу от Миссисипи приобрели товары красного цвета в июне?" Это запрос. Сам по себе возврат идентификатора во время вставки не является типичным запросом.

Как и в большинстве других вещей в разработке программного обеспечения, эта модель не является абсолютной. Даже Фаулер говорит, что готов сломать его, когда это будет удобно:

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

Если вы действительно хотите извлечь последний добавленный идентификатор из базы данных отдельно от ее вставки, вы можете использовать что-то вроде Scope Identity. Но я думаю, что вы добавляете сложность без дополнительной выгоды.

Способ сделать это - заставить вызывающего абонента указать идентификатор для нового объекта (что, скорее всего, подразумевает использование идентификаторов GUID в качестве ключа).

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

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