使用存储库模式使用子实体更新聚合根

时间:2013-11-19 15:44:12

标签: sql design-patterns repository-pattern

我将使用Invoice和invoiceLineItems的标准示例。所以我有一个发票的单一存储库,因为发票是聚合根。创建整个发票并删除发票非常简单。如何更新发票?

也许我不应该这么认为“低水平”,但我无法想象一个很好的方法来处理这个问题。这是我的这个操作的伪代码

public void Update(Invoice inv)
{
    var dbVersion = GetInvoice(id);
    foreach(var lineItem in inv.LineItems)
    {
        if (lineItem not in dbVersion)
        {
            InsertLineItem(lineItem);
        }
        else
        {
            UpdateLineItem(lineItem);
        }
    }

    foreach(var lineItem in dbVersion)
    {
        if (lineItem not in inv)
        {
            DeleteLineItem(lineItem);
        }
    }
}

我正在想象这个东西需要产生的查询,而且看起来非常低效。

  • 选择要重新生成整个发票的对帐单。
  • 整个发票的更新声明(无论发票上的任何内容发生变化)
  • 为每个新订单项插入声明
  • 已经存在的每个订单项的更新语句(无论是否有任何更改)
  • 删除缺少的每个订单项的语句

当然,您不必为整个发票和InvoiceLineItem生成更新语句,但这需要您检查每个中的所有属性。

如果您使用了IvoiceLineItemRepo,则只有在用户执行需要更新的操作时才会更新。因此,如果用户只更新了一行,那么只有一个更新和该订单项,您不必检查更改,您可以假设它已更改。

有更好的方法来处理更新吗?

1 个答案:

答案 0 :(得分:0)

你可以先删除LineItem集合,然后在hibernate中插入像all-delete-orphan这样的新集合。

deleteAllLineItemsByInvoiceId(Long id);
insertAllLineItems(List<LineItem> lineItems);