【问题标题】:Duplication of business logic in queries查询中的业务逻辑重复
【发布时间】:2017-09-01 10:29:42
【问题描述】:

在我正在处理的项目中,我有 DebtCollectionCase 对象,其中包含 Invoices, Payments, CreditNotes 等...我遇到的问题是查询数量一直在上升,而且还会继续上升,我在这些查询中有很多重复的一些计算。例如,计算得到UnpaidAmount 或Interest。这已经是一团糟了,而且随着时间的推移会变得更糟。

解决方案是将这些计算放在域对象中的函数中,然后可以在每个地方重复使用,但为此我需要在内存中获取整个聚合,这意味着应该获取 DebtCollectionCase, Invoices, Payments, CreditNotes然后只需调用函数来进行计算。单条记录应该没问题,但是当我需要这些清单时,数百个 DebtCollection 案例及其发票和付款。这将是获取大量数据并可能影响性能。

所以这是一个在内存中进行计算的问题,这对可重用性和维护性更好,并将业务逻辑放在查询中,这意味着更好的性能,但更难维护和违反 DRY。有人对我应该使用哪种方法有任何建议吗?

【问题讨论】:

  • 很可能您的域设计很糟糕。更具体地说,DebtCollectionCase“聚合”似乎太大了,并不能真正反映您的业务不变量。所以,我会从重新思考你的模型开始。如果你仍然认为它没问题(或者你不能改变它),我会选择特殊的“投影”只读模型,它由数据库高效查询支持(存储库模式可能适合你)。如果我理解您的问题,请告诉我。
  • 还有第三个选项,就是将结果计算缓存在属性中,并将它们存储在数据库中。它的复杂部分现在变成确保在状态的某些部分发生变化时重新计算属性,这本身可能很复杂(反应式编程技术可能会有所帮助),但它允许在保持查询的同时将业务逻辑保留在域中简单高效。
  • 我找到了一个解决方案,它叫DelegateDecompiler。它允许您在 linq Select 和 Where 语句中使用实体未映射的属性和函数,这意味着它们是可重用的,并且可以转换为 SQL,因此我不需要在内存中获取实体。如果有人需要,这里是链接github.com/hazzik/DelegateDecompiler。
  • @Aleksa 这很酷。您应该将其发布为答案。

标签: asp.net-mvc entity-framework web-applications domain-driven-design


【解决方案1】:

我找到了一个解决方案,它叫做DelegateDecompiler。它允许您在 linq Select 和 Where 语句中使用实体未映射的属性和函数,这意味着它们是可重用的,并且可以转换为 SQL,因此我不需要在内存中获取实体。如果有人需要Link to DelegateDecompiler,这是链接。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-07-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-02
    相关资源
    最近更新 更多