1

假设我的WinForms应用程序有一个商业实体订单,该实体用于多个视图,每个视图处理应用程序中的不同域或用例。例如,一个管理订单,另一个管理订单并显示其他数据。如果我使用nHibernate(或任何其他ORM)并使用一个会话/ dataContext每个视图(或每db动作),我最终会得到两个不同的实例为同一个订单(让我们说orderId = 1 )。尽管在功能上是相同的实体,但它们在技术上是两个不同的实例。是的,我可以实现Equals/GetHashcode以使它们“看起来”相同。商业实体:私人实例VS单个实例

为什么你会为每个实体的单个实例与每个视图或每个用例的私有实例进行比较?

单个实例具有共享INotifyPropertyChanged事件并共享额外(非持久性)数据的优势。

在每个视图中拥有一个私有实例会为您提供视图级别撤消功能的灵活性。在上面的示例中,我允许用户更改订单详细信息,并为他们提供了不保存更改的灵活性。这里,视图/用例之间的同步发生在数据持久性级别上。

你的论点是什么?

回答

2

应该实施Equals/GetHashCode方法。这是使用ORM时的推荐做法。

另外,您通常应该坚持使用“One View,One Session”口头禅。当视图改变或失去焦点时,坚持所有的对象。如果你真的需要共享视图实体...以及做到这一点!有时你必须。

再次,因为当我们从一个实体和行类型的角度来看业务对象时,我们不应该关注“对象”级别的等式。

+0

有趣......但为什么*你应该*实现等于/ gethashcode?换句话说,为什么ORM构建器不只是返回一个实体的单个实例并让.NET处理相等?我猜我想要的是基于场景的最佳实践,它最好去私人实例,而不是仅仅接受它的方式...... – tofi9 2010-03-17 10:58:15

+1

因为在大多数情况下,ORM *不能* 。假设**你**创建一个对象的实例。然后你坚持数据库。然后,使用ORM将相同的对象从数据库中拉出来。 ORM如何知道你更早实例化了那个对象?它所知道的只是缓存的内容。并且在很多情况下,对象上使用代理来协助跟踪已更改的属性。您*应该*实现它们,因为现在您可以比较对象之间的“业务对象”相等性。你真的关心它们是否是同一个实例吗?如果你这样做,保留你自己的缓存。 – snicker 2010-03-17 15:35:49

0

我不能说ORM的,但我认为你在某种程度上回答了你自己的问题。你已经提供了两种选择的优点和缺点:既不是绝对的,也不是错误的。

根据您的情况,选项只有对或错。如果共享信息有意义使用单共享实例,但是如果撤消能力更重要,则使用多个/私有实例。

您可能还有其他问题可以推动决策:考虑NFR(或“病态”)和系统环境。例如,如果性能是一个关键问题,并且您知道您将拥有庞大的用户群,那么这可能有助于提出一种选择,或者迫使您重新从头开始重新考虑。

最后 - 你有“订单”,其他实体怎么样 - 它们是如何处理的?
或者,如果你没有,会发生什么情况?这对您的架构会有任何想象吗?