代码之家  ›  专栏  ›  技术社区  ›  Pablo Cabrera

在数据库中缓存计算值(总和/总计)

  •  0
  • Pablo Cabrera  · 技术社区  · 7 年前

    客户->命令

    订单->&燃气轮机;OrderLineItems->产品{价格}

    该应用程序专注于处理订单,因此大多数显示符合特定条件的所有订单的时间表都在UI中使用。99%的时间我只对显示行总数感兴趣,而不是单个行总数。

    进一步考虑一下,每个订单也可能有多笔付款(电汇、支票、信用卡等),同样,我只对收到的金额感兴趣。

    我的想法是将每个订单与一个“status”对象相关联,缓存订单的所有金额和状态,按数量级提高查询性能,还支持未付款订单、已付款订单、到期订单等的查询场景。

    这可以防止域逻辑(例如,当订单被视为已付款时)泄漏到数据库查询中。然而,它将负责保持汇总的最新状态。系统通常有明确定义的需要执行的点,例如输入或整合付款、创建/修改订单。

    到目前为止,我使用了可观察的集合,当添加或删除项目,或者更新项目上的某些属性时,这些集合会触发状态的重新计算。我问自己,从ddd的角度来看,所有这些的逻辑应该放在哪里。对我来说,在聚合根中强制所有事件连接和计算逻辑似乎很奇怪。

    3 回复  |  直到 16 年前
        1
  •  1
  •   Mike Scott    16 年前

    你需要表达你的想法 意图 在意图显示界面中显示请求,以便您的存储库能够准确地理解您想要做什么并做出相应的反应。在这种情况下,接口向其他代码而不是其他开发人员显示意图。因此,如果需要状态或总数,请创建一个显示此意图的界面,并从存储库中请求该类型的对象。然后,存储库可以创建并返回一个域对象,该域对象封装了计算总数所需的全部工作,仅此而已。

    此外,DAL可以智能地选择从您请求的接口应用哪种抓取策略,即在不需要访问子对象的情况下延迟加载,在需要访问子对象的情况下快速加载。

    乌迪大汉有一些 great blog posts about this making roles explicit .

        2
  •  0
  •   jrista    16 年前

    我强烈建议研究支持LINQ的OR(对象关系)映射器。将两个主要的名称命名为LINQ To SQL和Entity Framework,它们都来自Microsoft。我相信LLBLGen现在也支持LINQ,nHibernate有一些半生不熟的LINQ解决方案可以尝试。我的主要推荐是EntityFrameworkV4.0,它可以通过.NET4.0Betas或VisualStudio2010测试版获得。

    通过启用LINQ或映射器,您可以轻松地仅使用域模型动态、实时地查询所需的聚合信息。业务逻辑不需要泄漏到数据层,因为您通常不会使用存储过程。或映射程序为您动态生成参数化SQL。LINQ与OR mappers相结合是一个非常强大的工具,它不仅允许您查询和检索实体和实体图,还允许您查询域模型上的数据投影……允许通过单个概念模型检索自定义数据集、聚合等。

        3
  •  0
  •   Martin R-L    16 年前

    “对我来说,在聚合根中强制执行所有事件连接和计算逻辑似乎很奇怪。”

    这通常是一个服务呼叫。