32

许多与 CQRS(命令查询响应)分离相关的 blogsphere 文章似乎暗示所有屏幕/视图模型都是平面的。例如姓名,年龄,出生地点等。因此建议我们将它们放入快速读取源等中。每个视图单个表 mySQL 等。然后使用原始 SqlDataReader 之类的东西将它们拉出来,踢那个讨厌的休眠ORM等。

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

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

我考虑过保持对查询数据库的直接 SQL 查询,断开外部连接,以便可以构建一个合适的 ViewModel 来查看,但这似乎有点矫枉过正?

或者(这开始感觉很糟糕)在 CustomerSummaryView 表中有一个名为 Orders 的文本/大(无论您的 DB 中的类型是什么)列,订单摘要屏幕网格的列由 分隔,行由 | 分隔。即使使用 XML 数据类型,它仍然感觉很脏。

关于最佳实践的任何想法?

4

5 回答 5

35

是的,出现了混乱。它是这样发生的:首先,为了真正帮助新人了解 CQRS 的全部内容,并真正了解它与典型的分层架构有何不同,人们会说“你的视图模型可以完全平坦”,和“您的 Query 数据库中的每个视图模型应该有一个表。”

但这实际上只是为了说明这一点……每个视图模型必须只有一个表是不正确的(尽管在大多数情况下您可能应该)。这些陈述试图表达的是:“你必须摆脱一些你长期以来遵循的关于规范化的规则。使用 CQRS 架构,你有机会在查询通道中创建数据库表完全根据您的视图的需要而定,仅此而已。确保充分利用这一点。不要仅仅因为这是您习惯的做法,就将这些表规范化一半。相反,继续做过去被认为是不可想象的事情,例如为每个视图模型制作一个数据库表,或者让您的视图模型表完全平坦。”

仍然存在像您这样的情况,其中最能满足您需求的模式将具有多个表。你甚至可以(上帝保佑)做一两次加入。没关系,只要您真的设计了数据库表来服务您的视图,反之亦然。但要小心,在 Query 数据库中的许多视图之间很容易滑下规范化和共享数据的斜坡。不要去那里......根本没有理由,它产生的成本大于收益。主要目标是:你的视图逻辑应该是死的,死的简单。您希望智能规则存在于房屋的命令端,以及在查询通道中填充数据的订阅者中的一点点。因此,从 Query 数据库读取数据并在屏幕上显示数据的代码应该非常简单(几乎与“被动视图”一样简单)。

更新:只要您设计了数据库形状以最好地服务于您正在实现的任务,就不会“禁止”执行某些连接的声明,请考虑使用OLAP。星型模式是旨在支持读取的数据库模式的完美示例,它非常适合 CQRS 的查询端,并且确实涉及连接。连接保持简单,它们可以进一步增强对数据库执行的读取任务的目标。

于 2010-03-07T23:10:22.073 回答
5

如果有人真的说你的视图模型应该是扁平的,那么他们要么过于简化了他们的例子,要么是在胡说八道。分层数据还不错,不应在您的视图模型中避免使用。

但是,确实没有“最佳实践”。加载数据的方式非常主观。您需要找到适合您当前团队和系统的解决方案。而且您还应该了解还有哪些其他选择,因为您可能会遇到当前解决方案不足的情况。

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

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

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

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

我敢肯定还有其他选择,但这些是我最常使用的三个,按照我使用它们的频率排列。他们都有自己的成本/收益。但要了解的重要一点是,您可以而且应该以一种便于您填充屏幕的方式检索数据。

于 2010-02-16T15:17:58.767 回答
4

我认为人们错过了 CQS(或 CQRS,实际上是一样的东西)的重点。CQR 只是一种模式,表示您应该有单独的读取和写入模型。这些模型是什么完全取决于您的实施要求。

最近谈论这个的人们通常会描述极其简单的架构和实现,以证明当今编写的大多数企业软件都是过度设计和过度设计的。

于 2010-07-17T01:28:34.503 回答
3

CQRS ES 方法的好处之一是您可以设计非常简单(快速读取)的视图数据。作为事件流的结果,您可以以任何您想要的方式塑造您的读取端数据。因此,很多人喜欢对数据进行反规范化,以便对其进行优化以供阅读。你当然不必。但你为什么不呢?考虑与写入相比,典型 LOB 中的读取频率。

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

于 2014-10-07T13:23:50.287 回答
2

如果您想在视图中使用不同的维度,那么这样做没有问题。值得注意的是,您不能在视图下方使用多个视图模型。非规范化器负责用正确的数据填充数据库视图。看看这篇文章,它解释了非规范化器是如何工作的,并且可能会让你在你的问题上朝着正确的方向前进。

于 2010-02-18T05:51:47.307 回答