CQRS - 查询端

发布于 2024-08-22 06:33:10 字数 526 浏览 4 评论 0原文

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

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

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

我考虑使用直接的 SQL 查询来查询数据库打破了外部联接,因此可以构建合适的 ViewModel 来查看,但这似乎有点矫枉过正?

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

关于最佳实践有什么想法吗?

A lot of the blogsphere articles related to CQRS (command query repsonsibility) seperation seem to imply that all screens/viewmodels are flat. e.g. Name, Age, Location Of Birth etc.. and thus the suggestion that implementation wise we stick them into fast read source etc.. single table per view mySQL etc.. and pull them out with something like primitive SqlDataReader, kick that nasty nhibernate ORM etc..

However, whilst I agree that domain models dont mapped well to most screens, many of the screens that I work with are more dimensional, and Im sure this is pretty common
in LOB apps.

So my question is how are people handling screen where by for example it displays a summary of customer details and then a list of their orders with a [more detail] link etc....

I thought about keeping with the straight forward SQL query to the Query Database breaking off the outer join so can build a suitable ViewModel to View but it seems like overkill?

Alternatively (this is starting to feel yuck) in CustomerSummaryView table have a text/big (whatever the type is in your DB) column called Orders, and the columns for the Order summary screen grid are seperated by , and rows by |. Even with XML datatype it still feeel dirty.

Any thoughts on an optimal practice?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

你げ笑在眉眼 2024-08-29 06:33:10

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

但这实际上只是为了让大家明白这一点……每个视图模型必须只有一个表是不正确的(尽管在大多数情况下您可能应该这样做)。这些陈述试图表达的是:“您必须摆脱长期以来一直遵循的规范化规则。借助 CQRS 架构,您有机会在查询通道中创建数据库表完全根据您的观点的需要而定,不要仅仅因为这是您习惯的做法而半途而废。过去被认为是不可想象的事情,例如为每个视图模型创建一个数据库表,或者使视图模型表完全平坦。”

仍然存在像您这样的情况,最能满足您需求的架构将具有多个表。您甚至可以(上帝禁止)进行一两次连接。没关系,只要您确实设计了数据库表来服务于您的视图,而不是相反。但要小心,很容易在规范化和在查询数据库中的许多视图之间共享数据的过程中下滑。不要去那里......根本没有理由,而且它带来的成本大于收益。主要目标是:您的视图逻辑应该非常简单。您希望智能规则位于房子的命令端,并在订阅者中保留一点,以填充查询通道中的数据。因此,从查询数据库读取数据并在屏幕上显示数据的代码应该非常简单(几乎与“被动视图”一样简单)。

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

Yeah, there's a confusion that arises. Here's how it happens: First, in order to really help new people understand what CQRS is all about, and to really drive home how it differs from the typical layered architecture, people say things like, "Your view models can be completely flat", and "You should have one table per view model in your Query database."

But that is really just meant to drive the point home ... it is not true that you must have only one table per view model (though in most cases you probably should). What those statements are trying to say is this: "You've got to shake yourself free of some rules that you've followed for so long about normalization. With the CQRS architecture, you have the opportunity to make database tables in your Query channel that are completely shaped according to the needs of your view and nothing else. Make sure you take full advantage of that. Don't go halfway by normalizing these tables just because it is what you're accustomed do. Instead, go ahead and do things that used to be considered unthinkable, such as making one database table per view model, or making your view model tables completely flat."

There are still cases such as yours where the schema that would best serve your needs would have multiple tables. You might even (God forbid) do a Join or two. That's fine, as long as you really have designed the database tables to serve your view, and not vice versa. But be careful, it is easy to slip down the slope of normalization and sharing data between many views in the Query database. Don't go there ... there's simply no reason and it incurs more cost than benefit. The main goal is this: Your View logic should be dead, dead simple. You want the intelligent rules living on the Command side of the house, and a little bit in the Subscribers that populate the data in the Query channel. So the code that reads from the Query database and shows data on a screen should be dead simple (almost as simple as a "passive view").

Update: As further backing for the statement that it is not "forbidden" to do some joins as long as you have designed the database shape to best serve the task you're achieving, consider OLAP. The star schema is a perfect example of a database schema designed to support reads, that fits perfectly in the Query side of CQRS, and that does involve joins. The joins are kept simple, and they are in place to further enhance the goals of the Read tasks performed against the database.

眼藏柔 2024-08-29 06:33:10

如果有人真的说你的视图模型应该是扁平的,那么他们要么过度简化了他们的示例,要么就是在胡说八道。分层数据并不坏,不应该在视图模型中避免。

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

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

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

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

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

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

if anyone is actually saying that your viewmodels should be flat, they are either oversimplifying their example or they are talking a bunch of nonsense. hierarchical data is not bad and should not be avoided in your viewmodels.

there really are no 'best practices' for this, though. it's all very subjective in how you load up the data. you need to find a solution that works well for your current team and system. and you should also understand what other options are out there because you'll probably run into a situation where your current solution is inadequate.

here are some of the ways I handle this, depending on the application i'm working on, in C# / .NET:

  • Datasets and straight ADO.NET, and bind the dataset directly to the screen's controls
    ** write straight SQL code to load the dataset
    ** use views in the database to load the dataset
    ** use stored procs to load the dataset

  • NHibernate and DTO / Viewmodel objects
    ** i typically use views when going down this route - I'll create a suite of views on top of my domain's schema, that denormalize the data into the model i need, and then use NH to load it up via a second set of maps

  • DTO / Automapper from domain model
    ** i don't like this approach unless I know that I already have everything from my domain model loaded in memory. i'll use a tool like Automapper to transfer data from my domain model into a DTO / ViewModel

i'm sure there are other options, but these are the three that i use most often, in order of how often i use them. they all have their own cost / benefits. but the important thing to understand is that you can and should retrieve the data in a manner that makes it easy for you to populate your screens.

2024-08-29 06:33:10

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

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

I think people are missing the point of CQS (or CQRS, same thing really). CQR is simply a pattern to say that you should have separate models for read and writing. What those model are is completely up to your implementation requirements.

Folks that been talking about this recently usually describe extremely simple architectures and implementation to drive home that the fact that most enterprise software written today is over-designed and over-engineered.

一人独醉 2024-08-29 06:33:10

CQRS ES 方法的好处之一是您可以设计非常简单(快速读取)的视图数据。由于事件流,您可以按照您想要的任何方式调整读取端数据。因此,很多人喜欢对数据进行非标准化处理,以便优化阅读。你当然不必这样做。但你为什么不呢?考虑一下典型 LOB 中读取频率与写入频率的比较。

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

One of the benefits of a CQRS ES approach is that you can devise really simple (read fast) view data. As a result of the event stream you can shape your read side data in any way you want. Hence lots of people like to de-normalise the data so that it is optimised for reading. You don't of course have to. But why wouldn't you? Think about the frequency of reads in a typical LOB compared to the writes.

Just in case you find it helpful and would like to see some code samples I have written a more detailed answer on my blog. You can find the post here: http://danielwhittaker.me/2014/10/05/build-master-details-view-using-cqrs-event-sourcing/

開玄 2024-08-29 06:33:10

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

If you want to work with different dimensions in your views, there are no problems to do that. There is noting saying you cant use multiple view models below a view. The denormalizer is responsible for populating the database views with correct data. Have a look at this post, it explains how the denormalizer works and may put you in the right direction concerning your question.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文