我正在使用以下应用程序结构在 C# 中开发 N 层应用程序。
我的解决方案结构。
- UI - WPF Prism 和 ViewModels 连接到服务。由商店员工使用。
- 服务 - WCF - 业务逻辑、数据检索和通过数据层连接到数据库。
- 实体 - EF POCO 实体 - 没有逻辑。
- 数据 - EF DbContext 和 EDMX - 数据库连接
- Web - ASP.NET MVC 应用程序 - 基于 Web 的 UI 版本,具有有限的功能和客户访问权限。连接到服务。
我想知道在哪里可以找到具有计算的实体对象的逻辑。
这是示例实体。
public class Invoice
{
public int InvoiceID { get; set; }
public DateTime InvoiceDate { get; set; }
public Decimal SubTotal { get; set; }
public Decimal? SalesTax { get; set; }
public Decimal? DiscountPercent { get; set; }
public Decimal? DiscountAmount { get; set; }
public decimal Total { get; set; }
public ICollection<InvoiceDetail> InvoiceDetails { get; set; }
}
public class InvoiceDetail
{
public int InvoiceDetailID { get; set; }
public int InvoiceID { get; set; }
public Decimal Quantity { get; set; }
public Decimal Price { get; set; }
public decimal Total { get; set; }
public Invoice Invoice { get; set; }
}
在上述场景中,当值发生变化时,我应该将计算发票总额的逻辑放在哪里。例如,更新的 SalesTax 将需要更改 Invoice Total。向发票添加行项目需要更改小计、税收、折扣和总计。
我想知道我是否可以在服务层中做到这一点并让实体贫血。我担心的是我需要不断地来回发送整个发票对象。
即使我还没有做移动解决方案,但不确定这在移动环境中是否是一个好主意,因为来回发送发票可能会消耗数据。
例如,另一个想法是在 InvoiceDetail 中使用 AddLineItem() 方法,在 Invoice 中使用 CalculateTotals() 方法。
AddLineItem 自动计算行项目的总计(我可以将其设为数据库中的计算列),并计算发票的小计、折扣、税款、总计。我假设在这种情况下,如果我想在内部调用CalculateTotals(),例如当SalesTax 更改而不是将其留给客户端调用CalculateChanges 时,我可能必须删除自动属性。那是对的吗?如果是,那么我将 EF 模板重构为不具有自动属性,而是具有支持字段的属性,这将成为一个问题。
请告知哪种方法更好,为什么?或者针对这种情况采用完全不同的方法。谢谢你的帮助。