首页 > 解决方案 > 当 InvoiceItem 项目更改时跟踪 Invoice 表上的 Amount 字段的最佳方法?

问题描述

我正在构建一个应用程序,我需要在其中存储客户的发票,以便我们可以跟踪谁支付了谁没有支付,如果没有,看看他们总共欠了多少钱。现在我的架构看起来像这样:

Customer
 - Id
 - Name

Invoice
 - Id
 - CreatedOn
 - PaidOn
 - CustomerId

InvoiceItem
 - Id
 - Amount
 - InvoiceId

通常我会使用 Entity Framework 获取所有数据并计算我的 C# 服务中的所有内容,(甚至在 SQL Server 上进行计算)如下所示:

var amountOwed = Invoice.Where(i => i.CustomerId == customer.Id)
                        .SelectMany(i => i.InvoiceItems)
                        .Select(ii => ii.Amount)
                        .Sum()

但是,每次我需要生成报告时计算所有内容这一次感觉不是正确的方法,因为我必须生成应该计算所有客户欠款的报告(有时在层次结构上甚至更高) .

对于这种情况,我正在考虑在我的表上添加一个Amount字段,Invoice并且可能AmountOwed在我的Customer表上添加一个字段,InvoiceService每当我插入/更新/删除一个InvoiceItem. 这应该足够安全,并使报表查询速度更快。

但我也一直在搜索关于这个主题的一些内容,另一种推荐的方法是在我的数据库上使用触发器。我最喜欢这种方法,因为即使我使用 SQL 而不是应用服务直接修改值,其他表也会自动更新。

我的问题是:

每当更改 InvoiceItem 时,如何添加触发器以更新所有父表?

根据您的经验,这是解决此问题的最佳(更安全,更不容易出错)解决方案,还是我遗漏了什么?

标签: c#sql-serverentity-framework

解决方案


首先,永远不要将触发器用于业务逻辑。触发器很棘手,很容易忘记。很难维护这样的应用程序。

在大多数情况下,您可以通过实体框架或 SQL 查询轻松填充您的报告数据。但如果它需要大量连接,那么您需要考虑使用临时表。因为报告需要数据非规范化。要填充临时表,您可以使用 SQL 作业或其他计划机制(可能是 Azure 计划程序)。这样您就不需要处理大量的联接,并且您的报告将更快地填充。


推荐阅读