11

CQRS 很有意义。然而,它似乎与使用提供变更跟踪的 ORM 的方法互斥。如果我有一个“通道”用于查询以将我的对象作为 RO,则无需跟踪任何更改。如果我有另一个 CUD+ 命令通道,它更像是一种带有轻型 DTO 的 RPC 方法,然后发送自跟踪实体以在较低层合并。

如何协调这两种方法(CQRS / ORM + STE)?

4

2 回答 2

8

构建 CQRS 应用程序的常用方法是在命令处理程序中对域模型进行操作。

您将发送命令 DTO,并在处理程序中调用域对象的方法(您不会设置域实体的属性,因为这是主要的反模式)。

域对象中的方法将负责修改域的内部状态。

那时,您的 ORM 将负责将更改持久化到域对象的内部状态。

这种构建 CQRS 应用程序的方式不使用事件溯源,但确实使用了 ORM 和自跟踪实体。

这是一个非常简化的示例。

public class AccountController 
{
  [HttpPost]
  public ActionResult ChangePreferredStatus(Guid accountId, bool isPreferred)
  {
    if (isPreferred) {
      // in response to user action, our controller commands our application to carry out an operation/state transition
      Bus.SendCommand(new MakeAccountPreferredCommand(accountId));
    }
  }
}

public class MakeAccountPreferredCommandHander : IHandle<MakeAccountPreferredCommand>
{
  public void Handle(MakeAccountPreferredCommand command) 
  {
    using (var uow = new UnitOfWork()) {
      var account = accountRepository.Get(command.AccountId);
      if (account != null) {
        // we tell the domain what we want it to do, we DO NOT fiddle with its state
        account.MakePreferred();
      }
      uow.Accept(); // accepting the uow saves any changes to self-tracked entities
    }
  }
}

public class Account : SelfTrackedEntity
{
  private Guid accountId;
  private bool isPreferred; // ORM tracked *private* state

  public void MakePreferred() 
  {
    // entities are responsible for their own state and changing it
    ValidateForMakePreferred();
    isPreferred = true;
    RaiseEvent(new AccountMadePreferredEvent(accountId));
  }
}
于 2011-04-08T19:25:40.347 回答
4

这些方法需要协调吗?

如果您使用 CQRS,为什么需要或想要更改跟踪?这不像您的对象正在往返。

在我当前客户端的实现中,我们在命令端使用带有 NoRM 的 MongoDB,在查询端使用带有 WCF 数据服务的 SQL Server 2008 R2。在命令端不需要实体框架,不需要实体跟踪,......而且它工作得很好!

于 2011-04-11T07:59:35.120 回答