CQRS - 查询方面

时间:2010-02-16 15:06:33

标签: nhibernate design-patterns orm command cqrs

许多与CQRS(命令查询可复制性)分离相关的blogsphere文章似乎暗示所有屏幕/视图模型都是平坦的。例如名称,年龄,出生地点等...因此建议明确我们将它们粘贴到快速读取源等。每个视图mySQL等单个表...并用原始的SqlDataReader拉出它们,踢出令人讨厌的nhibernate ORM等等。

然而,虽然我同意域模型不能很好地映射到大多数屏幕,但我使用的许多屏幕都更具有立体感,我相信这很常见 在LOB应用程序中。

所以我的问题是人们如何处理屏幕,例如它显示客户详细信息的摘要,然后是[更详细]链接等的订单列表....

我考虑过使用查询数据库的直接SQL查询来断开外连接,这样可以构建一个合适的ViewModel来查看,但它看起来有点过分了吗?

或者(这开始让人感到厌倦)在CustomerSummaryView表中有一个名为Orders的text / big(无论数据库中的类型是什么)列,Order order屏幕网格的列是分隔的,而行是按行分隔的。 。即使使用XML数据类型,它仍然很脏。

对最佳做法的任何想法?

5 个答案:

答案 0 :(得分:33)

是的,出现了混乱。以下是它的实现方式:首先,为了真正帮助新人了解CQRS的全部内容,并真正将其与典型的分层架构区别开来,人们会说“你的视图模型可以完全平坦”,和“您的查询数据库中每个视图模型应该有一个表。”

但这实际上只是为了推动这一点......你必须每个视图模型只有一个表(尽管在大多数情况下你可能应该这样)是不正确的。这些陈述试图说的是:“你必须摆脱一些你已经遵循规范化的规则。使用CQRS架构,你有机会在你的查询频道中建立数据库表根据你的观点的需要而完全塑造其他的东西。确保你充分利用这一点。不要因为这是你习以为常的事情而将这些表归一化。不过,继续做下去过去被认为是不可想象的事情,例如为每个视图模型创建一个数据库表,或者使视图模型表完全平坦。“

还有像你这样的情况,最能满足你需求的架构会有多个表。你甚至可能(上帝保佑)做一两次加入。这很好,只要你真的设计了数据库表来为你的视图服务,反之亦然。但是要小心,很容易在规范化的斜坡上滑动并在Query数据库中的许多视图之间共享数据。不要去那里......根本就没有理由,它会带来更多的成本而不是收益。主要目标是:您的View逻辑应该是死的,简单的死。您希望智能规则存在于房屋的Command端,并且需要在订阅服务器中填充查询通道中的数据。因此,从查询数据库中读取并在屏幕上显示数据的代码应该非常简单(几乎就像“被动视图”一样简单)。

更新:作为声明的进一步支持,只要您设计了数据库形状以最好地满足您正在实现的任务,就不会“禁止”进行某些连接,请考虑< strong> OLAP。星型模式是数据库模式的完美示例,旨在支持读取,完全适合CQRS的Query端,并且 涉及联接。连接保持简单,并且它们已经到位,以进一步增强针对数据库执行的读取任务的目标。

答案 1 :(得分:5)

如果有人真的说你的视图模型应该是扁平的,那么他们要么过于简单化他们的例子,要么他们正在谈论一堆废话。分层数据也不错,在视图模型中不应该避免。

但是,确实没有“最佳实践”。在加载数据方面,这一切都非常主观。您需要找到一个适合您当前团队和系统的解决方案。你还应该了解其他选项是什么,因为你可能会遇到当前解决方案不足的情况。

以下是我处理此问题的一些方法,具体取决于我正在使用的应用程序,在C#/ .NET中:

  • 数据集和直接ADO.NET,并将数据集直接绑定到屏幕的控件 **编写直接的SQL代码来加载数据集 **使用数据库中的视图加载数据集 **使用存储过程来加载数据集

  • NHibernate和DTO / Viewmodel对象 **我通常在沿着这条路线走时使用视图 - 我将在我的域模式之上创建一套视图,将数据反规范化为我需要的模型,然后使用NH通过第二组加载它映射

  • 来自域模型的DTO / Automapper **我不喜欢这种方法,除非我知道我已经从我的域模型加载到内存中的所有内容。我将使用像Automapper这样的工具将数据从我的域模型传输到DTO / ViewModel

我确定还有其他选择,但这些是我经常使用的三种选择,按我使用频率的顺序排列。他们都有自己的成本/收益。但要理解的重要一点是,您可以并且应该以一种方式检索数据,以便您可以轻松填充屏幕。

答案 2 :(得分:4)

我认为人们忽略了CQS(或CQRS,真的一样)的观点。 CQR只是一种模式,表示你应该有独立的读写模型。这些模型完全取决于您的实施要求。

最近讨论这个问题的人们通常会描述非常简单的架构和实现,以便将今天编写的大多数企业软件过度设计和过度设计这一事实带回家。

答案 3 :(得分:2)

如果您想在视图中使用不同的维度,那么这样做没有问题。有人说你不能在视图下面使用多个视图模型。 denormalizer负责使用正确的数据填充数据库视图。看看this帖子,它解释了非规范化程序的工作原理,并可能使您在正确的方向上解决您的问题。

答案 4 :(得分:2)

CQRS ES方法的一个好处是您可以设计非常简单(快速读取)的视图数据。作为事件流的结果,您可以以任何方式对读取的侧面数据进行整形。因此,许多人喜欢对数据进行去标准化,以便对数据进行优化以便阅读。你当然不必这样做。但是你为什么不呢?考虑典型LOB中与读写相比的读取频率。

万一你发现它有用并希望看到一些代码示例,我在我的博客上写了一个更详细的答案。您可以在此处找到帖子:http://danielwhittaker.me/2014/10/05/build-master-details-view-using-cqrs-event-sourcing/