用于相同会话更新的NHibernate级联行为

关于NHibernate级联设置的文档讨论了调用Save()Update()和Delete()方法的环境中的设置。 但是在隐式更新的上下文中,当我在同一个会话中加载,修改和保存实体时,我发现没有关于级联行为的讨论。 在这种情况下,不需要显式调用更新,那么关于级联设置会发生什么?

这似乎是一个愚蠢的问题,但我提出这个问题的原因是我想弄清楚NHibernate如何在域驱动设计的上下文中支持Aggregate Boundaries的概念。 让我举一个例子来说明我想要了解的内容。

假设我有实体Invoice,Buyer和LineItem的规范发票应用程序。 发票是一个聚合根,LineItem是在同一个聚合中,但买方是它自己的聚合根。

我想通过配置我的映射,使从发票到LineItem的级联是All-DeleteOrphans ,从发票到买方是None在NHibernate中对此进行建模。

根据我已阅读的文档,使用我想要的级联设置,如果我正在使用断开连接的实体,并执行以下操作,则只有发票和LineItems会保存:

disconnectedInvoice.ShippedDate = DateTime.Today();
disconnectedInvoice.LineItems[2].Backordered = true;
disconnectedInvoice.Buyer.Address = buyersNewAddress;

session.Update(disconnectedInvoice);
session.Flush();

我在任何地方都没有看到讨论的内容,当人们检索发票时,发生相同的更新并以如此连接的方式刷新会话时会发生什么情况。

var invoice = session.Get<Invoice>(invoiceNumber);
invoice.ShippedDate = DateTime.Today();
invoice.LineItems[2].Backordered = true;
invoice.Buyer.Address = buyersNewAddress;
session.Flush();

NHibernate文档说,flush会保留与会话关联的脏实体的更改。 基于这个假设,发票,买方和LineItems的更新都将被保留。

但是,这似乎违反了级联规则背后的概念。 在我看来,为了决定在刷新时更新哪些实体,会话应查看那些直接加载的实体(本例中仅为发票)并包含间接加载的实体(LineItems和此处的买方情况下)只有级联设置表明他们应该坚持。

我承认这个例子代表糟糕的DDD。 如果买方不是汇总的一部分,那么目前不应该更新。 或者至少它不应该通过发票集合进行更新。 但是,除了DDD之外,我实际上更感兴趣的一点是确定级联规则是否符合在同一会话场景中的更新,与在断开连接的场景中相同。


NHibernate文档说,flush会保留与会话关联的脏实体的更改。

主要问题是断开和连接实体之间的区别。 级联对于两者来说都是相同的,但它是不同的隐式更新。 对于会话加载的实体,不需要将保存级联给买方,因为它是多余的。 对于断开的实体,您需要级联,因为该买方不会有任何隐式更新,因为它从未明确地合并到会话中。

链接地址: http://www.djcxy.com/p/23241.html

上一篇: NHibernate Cascade Behavior for Same Session Updates

下一篇: childs save redundant sql update executed