【问题标题】:Loading a large and dynamically changing data set into a table将大型且动态变化的数据集加载到表中
【发布时间】:2013-10-24 21:38:26
【问题描述】:

我有大量数据,有时可能会在后台更新。作为一个自学实验,我不希望依赖任何框架。现在我正在尝试在 DDD/CQRS 上下文中找到 MVC/MVVC 模式的正确位置。

为了填充表,我对大型数据集进行了查询,并将结果限制为显示行数的两倍。一旦用户滚动超过一半的查询,我就会查询下一批结果。

当用户滚动时,我将所有结果加载到一个数组中,这只是一个渐进式加载,不会丢弃未显示的行。

谁负责构建转换为域对象的结果数组? MVC 的模型还是数据存储库?

理想情况下,我想重用我的 MVC 模型,而不必总是担心限制查询结果。

如果在后台更新数据,则会创建一个系统事件。但是,在创建新行的情况下,我希望我的应用程序为新行的背景插入设置动画,而不仅仅是丢弃查询并重新加载表。在这种情况下,我猜后台进程必须加载当前查询的副本并将其与现有查询进行比较。它应该使用新行的位置创建一个“新行系统事件”。

哪个组件应该将当前查询结果与之前的查询结果进行比较以计算插入点和删除点?系统服务? MVC 模型?

我最后担心的是,如果数据在后台更新,加载具有多个有限查询的一组行可能会不一致。我应该如何/在哪里强制执行这种一致性?

【问题讨论】:

  • 显示的数据在某种程度上总是陈旧的。为什么不让用户刷新或让系统定期刷新。
  • 考虑到 CQRS 架构,如果用户请求新行,则命令和查询是异步事件。我认为在这种情况下,如果您想尽快呈现新的空行,只能是系统而不是用户,他们根据数据库的更新时间决定何时重新加载查询,而不是何时用户单击新行的按钮。
  • 我认为客户端负责检测数据变化(通过定期扫描),否则服务器需要广播一个dataUpdatedEvent(我认为这很浪费网络)或者保留一个客户端备忘录来决定哪个客户对更新感兴趣(我认为这会增加很多复杂性)。嗯……StackOverflow 上的评论通知功能是如何实现的?
  • 对我来说何时更新查询无关紧要。更新数据库时,我已经有一个 Event 对象。我的问题是关于 (1) 我应该在哪些模式/组件中构建部分查询结果,以及 (2) 比较与以前查询的差异以动画插入或删除。
  • 看看 SignalR,以便在数据发生变化时将数据推送到客户端。

标签: design-patterns model-view-controller domain-driven-design cqrs


【解决方案1】:

CQRS 和 DDD = 一种域模型和至少一种查询模型。现在,为了您自己的利益,不要将 DDD 视为具有许多违反规则的东西,这将使您成为 DDD 公敌第一号。

让我们想一想:一旦更新了域对象并发布了域事件,您将拥有一个事件处理程序,它将更新查询模型。哪个查询模型正是您需要的 UI(视图模型)。

客户端 UI 应每隔一段时间请求更新(传递当前模型的日期时间戳)。哪些更新也是查询模型的一部分。为了检测发生了什么变化,更新应该有一个日期时间戳,它将与当前显示的时间戳进行比较。如果它是一个网络应用程序,那么我强烈建议使用像 angularjs.org 这样的 js 框架

现在,此场景中的 MVC 模型是查询存储库。当插入/编辑一行时,模型将是一个服务(或命令处理程序),它将更新域。与域更改和查询模型生成相关的所有内容都在 UI 之外,作为服务/应用程序(随意调用)层的一部分。

【讨论】:

  • 不错!所以在 MVC 中,模型应该是应用程序和域层之间的服务,对吧?我使用 NoSQL 数据库,它在触发 mapreduce 函数时向我发送一条消息,因此我不需要请求更新。每当我的 repos 返回一系列根对象时,我都会返回一个自定义 Array 类,它为我提供了一些延迟加载。我现在正在考虑使用时间戳扩展该类,甚至可能是在我的存储库中创建期间设置的 UID ......但这看起来不像我以前见过的东西。会不会太疯狂了?然后 repos 应该管理查询的年龄:/
  • MVC 模型表示 UI 可用的其他层的位。 MVC 仅存在于 UI 中。无论使用什么数据库,UI 都应该要求更新。此外,延迟加载 (LL) 的概念在此处或存储库模式中都没有位置。 LL 是一种 ORM 解决方法,把它留在那里。查询存储库应返回 UI 所需的任何内容作为 DTO。查询模型的更新在 UI 或 db 之外完成。 db 只是持久化更改,但另一个组件管理该过程。再一次,不要太担心层是如何被调用的。我更喜欢称它为服务,但这只是我的意见
  • 谢谢!在发表评论后,我意识到我的 CustomArray 不应该有 UID 或时间戳,因为只有某些模型才需要它。但是,您让我想到“查询存储库返回 UI 需要作为 DTO 的任何内容”。在 CQRS 之前,我的存储库仅返回根实体 (List),但由于 CQRS 的查询部分可以与域的实体分开,我添加了 List。哦,那是一个完全不同的问题,我必须回顾一下我对 CQRS 的了解
  • 天啊!我刚刚在自己的代码中意识到,在过去,我使用我的 CustomArray 通过缓存对 Repo.FindByID() 的内部调用来模拟 LL outise 用于大型查询结果的 repo。现在有了你的回答,我会让一些神经元工作,但我将不得不评估在屏幕/应用层上对 DTO 进行“修订”的技巧,这与在域层上对实体的“修订”不同,谢谢@MikeSW
猜你喜欢
  • 2015-09-15
  • 2017-11-16
  • 1970-01-01
  • 2016-03-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-30
  • 2021-11-12
相关资源
最近更新 更多