首页 文章

在CQRS中从写入侧读取数据库中的数据

提问于
浏览
4

Background :

解释CQRS的图表通常会明确区分读写路径和单向数据流,如本示例所示(来源:Demystified CQRS):
enter image description here

Question :

我想澄清一下,

如果后端的Command执行需要数据库中的某些数据,

  • "write side"应该有来自write database的读取功能吗?

  • 或它应该完全依赖"read side"进行任何读取?

  • 或者命令应该包含调用者提供的所有必需数据?

2 回答

  • 4

    “写入端”是否应该具有写入数据库的一些读取功能?

    可能 - 加载将要运行命令的实体的最直接方式是从“写入数据库”中读取其状态 . 例如,在事件源体系结构中,通常通过从写入模型加载该实体的历史记录,从该历史记录中重新水化该实体,评估该命令以及将新的更改附加到历史记录来处理更新事件源实体的命令 .

    读取关于不处理命令的实体的状态是另一回事 - ddd词汇在这里有帮助;您正在修改的状态只属于一个聚合,只要有可能,就应该将生成在聚合之外的状态传递给模型,而不是提取 .

    这可能意味着远程客户端需要提供数据,或者它可能意味着处理命令的应用程序获取所需的读取模型并提供答案 . 有许多不同的问题可以推动您在这里做出的选择

    • 如果客户端在生成命令时使用的读取模型与应用程序在处理命令时使用的视图明显不同,则存在一些风险 .

    • 保持稳定的API允许您自由地重新设计模型中的聚合边界,而无需更新客户端) .

    所以没有一个最好的答案,只需在不同的关注点之间进行权衡 .

    后一个最近的例子出现了 - 如果你的商业模式要求某些命令需要特定用户的权限,那么我们就不应该从客户端获取面值的命令;我们需要应用程序来验证命令发布者的身份,然后将该身份的表示传递给模型,以便它可以确定要采取的操作 .

  • 0

    @Edgars,

    根据我的经验,您的命令处理程序可以“读取”“只读数据读取器”中的数据 . 您用于模型的相同内容 .

    public class CreateNewSantaCommandHandler: ICommandHandler<CreateNewSantaCommand>
    {
        public IReadOnlyRepo<SomeDTO> readOnlyRepo;
        public ISantaRepo<Santa> santaRepo;
    
        // Inject the repos in the constructor, etc. You get the idea.
    
        public void Execute(CreateNewSantaCommand command)
        {
            var suit = readOnlyRepo.GetSuit(command.suitType) //Data you need
            var santa = Santa.New(command); //Factory method;
            santa.GetDressedPlease(suit);
            santaRepo.Add(santa);
            santa.Save() // this shouldn't be here. Usually higher level. UOW.
        }
    }
    

    是否有意义?

相关问题