Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/308.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在数据库中缓存计算值(总和/总计)_C#_Domain Driven Design_Query Optimization - Fatal编程技术网

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

C# 在数据库中缓存计算值(总和/总计),c#,domain-driven-design,query-optimization,C#,Domain Driven Design,Query Optimization,考虑以下对象模型(->表示集合): 客户->订单 订单->>订单行项目->产品{Price} 该应用程序专注于处理订单,因此大多数显示符合特定条件的所有订单的时间表都在UI中使用。99%的时间我只对显示行总数感兴趣,而不是单个行总数 进一步考虑一下,每个订单也可能有多笔付款(电汇、支票、信用卡等),同样,我只对收到的金额感兴趣 在查询数据库中的订单时,我不希望选择所有订单,然后选择每个订单的付款和行项目 我的想法是将每个订单与一个“status”对象相关联,缓存订单的所有金额和状态,按数量级提高

考虑以下对象模型(->表示集合):

客户->订单

订单->>订单行项目->产品{Price}

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

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

在查询数据库中的订单时,我不希望选择所有订单,然后选择每个订单的付款和行项目

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

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


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

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


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

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

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

乌迪大汉有一些。他曾撰写并讨论过如何将意图揭示接口应用于这个问题,他称之为。

“我觉得在聚合根中强制所有事件连接和计算逻辑似乎很奇怪。”


这通常是对«服务»的调用。

我已经使用了OR映射器(LinqToSql),并且我已经使用了标准组合和投影。这是关于数据库性能的,我必须查询每个视图大约10000个订单。它有点像(选择n)+ 1的问题,问题不仅仅是计算总数,而是如何计算,因为当我想计算总数时,我需要所有的数据,这就是为什么我在数据库中考虑“缓存”的原因,这就是我所要做的。你的意图要求你需要所有的数据,所以你必须给出这个“提示”。您的数据访问技术。通过在接口中明确角色,您的DAL可以选择适当的抓取策略,不管是懒惰还是渴望——但我重复我自己——这就是我在回答中所说的。我不知道你为什么认为它不能回答这个问题:-(我不想一次又一次地计算数据,因为这意味着我必须从数据库中加载所有数据,我不想这样做,因为这会严重影响性能!我希望数据(计算的总和)有点“缓存”在db中,因此我可以仅为只读目的获取它们。我的问题是如何保持缓存有效/当前。啊,对不起,Johannes,我的错误。我建议您查看域事件以处理此()。例如,每当发生更新总计的事件时,您都会引发一个域事件。您可以在域事件中传递增量,然后将其添加到总计中,而无需重新计算。这看起来是一个不错的方法。请编辑您的帖子/使其成为社区wiki,我会这样做,并将其标记为答案。这个问题是否如此简单有意思?我觉得很有意思。不过我不知道该怎么处理。