2

我正在使用 n 层方法将大型 Classic ASP Web 应用程序转换为 ASP.Net MVC。在我的 DAL 中,我使用 ADO.Net 来查询数据库并将查询转换为对象。我还有一个用于计算和验证之类的 BLL。

我的问题涉及在需要计算以将查询转换为对象时在 DAL 中执行计算。举个例子,考虑一个带有摘要信息和行项目的发票系统:

public class Invoice
{
    public int InvoiceID { get; set; }
    public DateTime InvoiceDate { get; set; }
    public decimal InvoiceTotal { get; set; }
    public List<InvoiceLineItem> LineItemList { get; set; }
}

因此,我在数据库查询中转换行项目的代码如下所示:

decimal InvoiceTotal = 0;
var LineItem = new InvoiceLineItem();
while (Reader.Read())
{
    LineItem.ItemID = Extensions.SafeGetInt(Reader, "ItemID");
    LineItem.Price = Extensions.SafeGetDecimal(Reader, "Price");
    LineItem.Quantity = Extensions.SafeGetInt(Reader, "Quantity");
    LineItemList.Add(LineItem);

    InvoiceTotal = InvoiceTotal + (LineItem.Price * LineItem.Quantity);    
}

Invoice.InvoiceTotal = InvoiceTotal;
etc ...

所以这是我的问题:考虑到我的 n 层架构,我的 DAL 是执行 InvoiceTotal 计算的正确位置吗?考虑到 BBL 的部分工作是执行计算,这是否违反了 DAL 和 BLL 之间的关注点分离?或者我是否过于从字面上理解了 BBL 执行计算的功能,如果需要这些计算来填充模型,可以在 DAL 中进行计算?我发现在 DAL 中进行 InvoiceTotal 计算很有吸引力的一个原因是因为我只需对发票项目记录进行一次迭代。如果我在其他地方创建了一个单独的 InvoiceTotal 函数来获取 InvoiceTotal,那么我将不得不再次遍历记录。

编辑:事实证明,真正的问题不是 DAL 中是否应该允许计算,而是 InvoiceTotal 是否应该在我的模型中。从数据库规范化的角度来看,它不是必需的,因为可以从行项目计算总数。在这种情况下,InvoiceTotal 不应该在我的模型中,而应该在我的 ViewModel 中,在这种情况下,不需要在我的 DAL 中进行计算。出于性能原因,我可以忽略数据库规范化问题,并在我的模型中包含 InvoiceTotal,但如果是这种情况,我会将 InvoiceTotal 持久保存到数据库中,在这种情况下,在填充我的模型时不需要计算,因为我只需从中提取值数据库。

经验教训:如果我想在 DAL 中进行计算,我的模型可能存在缺陷。

4

1 回答 1

3

我会将计算添加到业务逻辑层

发票总额的初始计算应该在您将其写入数据库之前在应用程序中可用,因此您不希望在检索记录时计算总额的唯一位置。

将它添加到业务逻辑层的另一个很好的理由是它可以从 DAL 返回的行数据派生,这将使 DAL 层专注于写入和读取数据。这也将您的计算保存在一个地方。

但是,由于发票总额在发送后是固定的,您可能希望在第一次保存时写入初始值,然后允许手动修改。在这种情况下,发票总额计算将在业务层中完成,但该值也将写入数据库并从数据库中检索,无需重新计算。

于 2014-01-11T15:41:40.663 回答