使用MVC控制器中的命令查询分离原则

时间:2012-05-03 14:45:47

标签: c# asp.net-mvc command-query-separation

我喜欢Command Query Separation的想法,但看不到如何在添加实体的MVC Controller操作中使用它,并且在添加实体后需要新实体的ID。

例如,在下面的简化示例中,服务用于创建新项目:

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

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

但是当我重定向到要显示新项目的操作时,我需要知道新创建的项目的ID,以便可以从数据库中检索它。所以我必须要求服务返回新创建的项目(或至少返回其ID)。

在纯CQS中,命令没有返回值,因此上面的模式将无效。

感谢任何建议。

3 个答案:

答案 0 :(得分:8)

我认为你陷入了迂腐的角色。

查询是指您想向数据库询问一个问题,例如“密西西比河以西有多少客户在六月份购买了红色物品?”这是一个查询。插入期间返回ID本身并不是典型的查询。

与软件开发中的大多数其他事情一样,这种模式不是绝对的。即使Fowler说他愿意在方便的时候打破它:

  

弹出堆栈是修改状态的修饰符的一个很好的例子。   梅耶正确地说你可以避免使用这种方法,但确实如此   一个有用的成语。所以我喜欢在可以的时候遵循这个原则,但是   我准备打破它以获得我的流行音乐。

如果您确实想要从数据库的插入中单独检索最近添加的ID,则可以使用Scope Identity之类的内容。但我认为你增加了复杂性,没有额外的好处。

答案 1 :(得分:4)

你应该向AssignItem方法传递一个“项目”(或你的实体名称是什么)的实例,它是从viewmodel的值创建的,然后该方法不必返回任何内容,而是只更新实体的Id属性使其成为Command方法。

然后,您可以将entity.Id用于任何您想要的内容

答案 2 :(得分:0)

这样做的方法是让调用者指定新实体的ID(这很可能意味着使用GUID作为键)。

但是,根据我的经验,强制执行命令可能不会返回结果的(纯粹)规则会导致问题,而收益甚微。