由于我正在研究一个相对复杂的问题,我想使用领域驱动设计方法来解决这个问题。有问题的问题是为客户计算月度发票。当前解决方案是作为非常长的存储过程实现的,难以维护。
我想使用面向对象的环境(可能是POCO和实体框架),但我担心性能。当前 SP 使用集合操作生成超过 300,000 条记录大约需要 10 分钟。我认为这很难用任何ORM实现,因为它会一个接一个地加载实体并以相同的方式发送更新。(以前的版本在逐个访问记录时需要 5 个小时。
如何为大规模运营创建丰富的模型?
在应用富域模型时,我尽可能避免使用大量操作。
某些批次可以替换为事件。例如,我需要每日订单盘点报告。
批处理解决方案:
在一天结束时触发的计划任务从今天下达的订单中收集数据。
或使用事件
PlaceOrderService 会在下新订单时发布 OrderPlacedEvent。事件处理程序接收事件并插入到T_ORDER_COUNT_ENTRY
|TODAY |ORDER_ID|
|2012-04-01|123 |
|2012-04-01|124 |
我们可以使用 SQL count() 来计算每日订单计数报告。
其他一些批处理可以并行运行。例如,如果在 30 分钟内未付款,我的订单应自动取消。
原始批处理解决方案是逐个获取所有满足的订单并调用它们的 cancel()。
当前的解决方案是逐个获取所有满足的订单,并发送OrderIsOverdue消息。消息处理程序接收包含 orderId 的消息,并检索订单,然后取消。
我认为当取消操作花费的时间远远超过发送消息时,这很有用。如果硬件资源可以承受,可以添加更多的消息处理程序来改进 虽然。
经过思考,我意识到你的问题与此类似:
如何将存储过程重写为域驱动的代码?
从理论上讲,这是可能的。您需要做的就是识别和分离存储过程中存在的问题,并以面向对象的方式重写它们。
话虽如此,我预计要为此目标解决以下类型的任务:
1 - 数据预加载
存储过程可以使用临时表或表类型的变量,这些在域驱动的代码中不可用。因此,它归结为预加载实体。这样做是为了提前加载所有数据,而无需稍后在迭代每个实体时加载依赖/子实体 - 您需要将它们全部放在内存中。
为此,请参阅 [聚合根]
这种方法有一个很大的缺点:内存消耗高。因此,下面的下一步。
2 - 无需预加载的数据迭代
存储过程具有游标之类的东西。这不会加载数据,而是以有效的方式迭代数据。但是,在域驱动的代码中,您无法真正实现完全相同的效果。有一些接近游标的东西 - [SqlDatReader],但它并没有真正在幕后使用 SQL 游标,所以要小心它。
3 - 批量数据修改
通过在域模型中正确实现[工作单元],可以轻松实现这部分。因此,即使您逐个调用实体实例上的修改操作,所有修改也会立即提交到数据库。
我不确定这是否为问题增添了一些线索,但如果您有任何我可以解决的意见,请告诉我。