Question

I like the idea of Command Query Separation but can't see how to use it within an MVC Controller action which is adding an entity, and needs the new entity's ID after adding it.

For example, in the simplified example below a service is used to create a new item:

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

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

But when I redirect to the action which is going to display the new item, I need to know the ID of the newly created item, in order that it can be retrieved from the database. So I have to ask the service to return the newly created item (or at least, its ID).

In pure CQS, a command has no return value, so the pattern above would be invalid.

Any advice gratefully received.

Was it helpful?

Solution

You should pass to AssignItem method an instance of "Item" (or whatever your entity's name is) that is created from the viewmodel's values, then the method doesnt have to return anything, instead it will just update entity's Id property making it a Command method.

You can then use entity.Id for anything you want

OTHER TIPS

I think you're stuck on a pedantic point.

A query is when you want to ask the database a question, like "How many customers west of the Mississippi purchased red colored items during the month of June?" That's a query. Returning the ID during an insert is not a typical query, per se.

As with most other things in software development, this pattern is not an absolute. Even Fowler says he's willing to break it when it is convenient to do so:

Popping a stack is a good example of a modifier that modifies state. Meyer correctly says that you can avoid having this method, but it is a useful idiom. So I prefer to follow this principle when I can, but I'm prepared to break it to get my pop.

If you really want to retrieve the most recently-added ID from a database separately from its insertion, you can use something like Scope Identity. But I think you're adding complexity for no additional benefit.

The way to do that would be to make the caller specify the ID for the new entity (which most likely implies using GUIDs as the key).

However, in my experience, imposing the (purist) rule that a command may not return a result is going to cause problems for little gain.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top