mbn*_*bnx 5 c# database-design nosql cqrs
我们使用域侧的关系数据库和读取端的NoSQL DB构建了基于CQRS的系统.域侧遵循经典的关系方法,而读取侧是非规范化的.使用命令处理程序发出的事件完成数据复制和转换.
我有两个关于读取端同步的问题:
使用域侧的关系数据完全重建读取模型的最佳方法是什么?
我们假设读模型不同步.但即使它始终保持同步,也可能需要导入测试数据库或进行一些批量操作.因此,人们可能希望从现有的写模型运行系统,而不需要相应的同步读模型.由于我们不使用Event Sourcing,因此无法重播所有事件.
我目前考虑ReadModelBuilder在每个表上基本上执行SELECT*FROM并将每个实体转换为读取端表示.但这引入了冗余.ReadModelBuilder需要知道转换是如何完成的.事件处理程序也是如此,它通常在命令处理程序执行某些写操作后执行读取端同步.
我考虑丢弃事件处理程序,并在每个类级别上用同步机制替换它们.例如,它将调用重写完整
实例的代替FooRenamedEventHandler重命名.但我认为这有弊端.FooRenamedEventHandler可以更好地处理读取模型中的冗余使用.foo.nameFooReadModelBuilderFoofoo.name
更新:
另一种方法可以是ReadModelBuilder通过将域实例分段为事件来创建读取模型实体,这将在顺序执行时构建完整的读取端实体.例如:
Article域实体有a Name和a Price.要构建读取端模型,ReadModelBuilder可以检查域实体并发出ArticleCreatedEvent,ArticleRenamedEvent和ArticlePriceChangedEvent.这样,转换逻辑将保留在事件处理程序中,但仍可从某种批量复制机制中调用.
例如,ReadModelBuilders可能如下所示:
_
interface IReadModelBuilder<TEntity>
{
//// Returns a sequence of events which replicate the read-model
//// when executed by the event handlers.
Event[] GetReplicationSequence(TEntity instance);
}
Run Code Online (Sandbox Code Playgroud)
更新结束
_
先感谢您.
如果您不持久化该事件(即不使用Event sourcing),那么您将无法轻松重建read-model. 您Rebuilder必须以某种方式尝试对写入模型进行逆向工程并伪造一些奇怪的事件,因为它们write model甚至无法包含所有信息,因为它不需要它来完成他的工作。
所以,我的结论是,如果没有event store或至少没有event log那么你就无法重建你的read-model. 如果您有这样的事实来源,那么您可以重建它,甚至可以通过在某种持久性中使用所有已处理事件 ID 的列表来检测不同步情况。