6

我喜欢命令查询分离的想法,但看不到如何在添加实体的 MVC 控制器操作中使用它,并且在添加后需要新实体的 ID。

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

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

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

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

在纯 CQS 中,命令没有返回值,所以上面的模式是无效的。

感激地收到任何建议。

4

3 回答 3

8

我认为你被困在一个迂腐的观点上。

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

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

弹出堆栈是修改状态的修饰符的一个很好的例子。Meyer 正确地说您可以避免使用这种方法,但它是一个有用的成语。所以我更愿意尽可能地遵循这个原则,但我准备打破它以获得我的流行。

如果你真的想从数据库中检索最近添加的 ID,而不是插入它,你可以使用类似Scope Identity的东西。但我认为你增加了复杂性而没有额外的好处。

于 2012-05-03T14:53:52.570 回答
4

您应该将AssignItem根据视图模型的值创建的“Item”(或任何您的实体名称)的实例传递给方法,然后该方法不必返回任何内容,而是只需更新实体的 Id 属性使其成为 Command 方法。

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

于 2012-05-03T15:02:44.053 回答
0

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

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

于 2012-05-03T15:07:20.147 回答