CQRS是否与实体框架自我跟踪实体/ WCF RIA服务兼容?

Jos*_*ben 10 entity-framework cqrs wcf-ria-services

CQRS有很多意义.但是,使用提供更改跟踪的ORM的方法似乎是相互排斥的.如果我有一个"通道"用于查询以将我的对象作为RO,则无需更改跟踪.如果我有另一个CUD +命令通道,它更多的是带有光DTO的RPC方法,然后发送自跟踪实体以在较低层合并.

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

que*_*rin 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));
  }
}
Run Code Online (Sandbox Code Playgroud)

  • 如果你将STE传递给视图,让它们填充在那里,然后将它们传递回上下文以获得保存,这绝对不是CQRS**.期.在该方案中,您的命令端和查询端未分开. (2认同)
  • 可以想象在CQRS的最基本定义下扭曲这样的方案,但是这种架构实际上是CQRS的对立面.在基于CQRS的架构中,我们告诉我们的实体做某事(即调用方法),我们不会用单个数据位填充它们.这严重违反了封装.此外,我很难看到如何使用填充的STE显式建模命令,并且显式建模命令(和事件)是基于CQRS的体系结构的核心原则. (2认同)