Winforms 业务实体:私有实例与单个实例

Winforms 业务实体:私有实例与单个实例,winforms,nhibernate,entity-framework,architecture,business-objects,Winforms,Nhibernate,Entity Framework,Architecture,Business Objects,假设我的WinForms应用程序有一个业务实体顺序,该实体在多个视图中使用,每个视图处理应用程序中不同的域或用例。例如,一个管理订单,另一个挖掘一个订单并显示附加数据 如果我使用nHibernate(或任何其他ORM)并对每个视图(或每个db操作)使用一个会话/数据上下文,那么我最终会得到相同顺序的两个不同实例(假设orderId=1)。虽然功能上是相同的实体,但在技术上它们是两个不同的实例。是的,我可以实现Equals/GetHashcode使它们“看起来”一样 为什么要选择每个实体的单个实例

假设我的WinForms应用程序有一个业务实体顺序,该实体在多个视图中使用,每个视图处理应用程序中不同的域或用例。例如,一个管理订单,另一个挖掘一个订单并显示附加数据

如果我使用nHibernate(或任何其他ORM)并对每个视图(或每个db操作)使用一个会话/数据上下文,那么我最终会得到相同顺序的两个不同实例(假设orderId=1)。虽然功能上是相同的实体,但在技术上它们是两个不同的实例。是的,我可以实现Equals/GetHashcode使它们“看起来”一样

为什么要选择每个实体的单个实例,而不是每个视图或每个用例的私有实例

拥有单个实例具有共享INotifyPropertyChanged事件和共享其他(非持久性)数据的优势

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

您的论点是什么?

您应该实现
Equals
/
GetHashCode
方法。这是使用ORMs时的推荐做法

此外,您通常应该坚持“一个视图,一个会话”的原则。当视图更改或失去焦点时,保留所有对象。如果您真的需要跨视图共享实体。。。好吧!有时你必须这样做


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

我不能代表ORM发言,但我认为你在某种程度上回答了你自己的问题。您已经提供了两种选择的利弊:从绝对意义上讲,两者都不是对的,也不是错的

选择的正确与否取决于你的情况。如果共享信息有意义,请使用单个共享实例,但如果撤消功能更重要,请使用多个/专用实例

你也可能有其他的顾虑来推动决策:想想NFR(或“非法性”)和系统的上下文。例如,如果性能是一个关键问题,并且您知道您将拥有大量的用户群,那么这可能有助于建议一个选项而不是另一个,或者迫使您从头开始重新思考

最后-你有“订单”,其他实体呢-它们是如何处理的?

或者,如果你没有,当/如果你有,会发生什么?在您的体系结构上会有任何imapct吗?

很有趣……但是为什么要实现equals/gethashcode呢?换句话说,为什么ORM构建器不只是返回实体的一个实例并让.NET处理相等性呢?我想我的目标是基于场景的最佳实践,在这个场景中,最好使用私有实例,而不是仅仅接受这种方式……因为在大多数情况下,ORM不能。假设您创建了一个对象的实例。然后持久化到数据库。然后使用ORM将同一对象从DB中拉出。ORM如何知道您之前实例化了该对象?它只知道缓存了什么。在许多情况下,在对象上使用代理来帮助跟踪已更改的属性。您应该实现它们,因为现在您有了比较对象之间“业务对象”相等性的方法。你真的在乎他们是否是同一个例子吗?如果你这样做了,保留你自己的缓存。