3

我想知道人们使用什么策略来处理主从设置中的实体的创建和编辑。(我们的应用程序是一个支持互联网的桌面应用程序。)

以下是我们当前处理此问题的方式:在弹出窗口中为需要编辑的实体创建一个表单,我们为其提供对象的副本。当用户单击“取消”按钮时,我们关闭窗口并完全忽略该对象。当用户点击“确定”按钮时,通知主视图并接收编辑的实体。然后,它使用 originalEntity.copyFrom(modifiedEntity) 将修改后实体的属性复制到原始实体中。如果我们想创建一个新实体,我们将一个空实体传递给弹出窗口,然后用户可以编辑它,就像它是现有实体一样。主视图需要决定是将接收到的实体“插入”还是“更新”到它管理的集合中。

我对上述工作流程有一些疑问和意见:

  • 谁应该处理实体副本的创建?(主或细节)
  • 我们使用 copyFrom() 来防止必须替换集合中的实体,这可能导致引用中断。有一个更好的方法吗?(实现 copyFrom() 可能很棘手)
  • 新实体收到 -1 的 id(服务器层/休眠使用它来区分插入或更新)。在保存实体之前按 id 查找(缓存)实体时,这可能会导致问题。我们应该为每个新实体使用一个临时的唯一 id 吗?

任何人都可以分享提示和技巧或经验吗?谢谢!

编辑:我知道这个问题没有绝对错误或正确的答案,所以我只是在寻找人们分享他们处理主要/细节情况的方式的想法和优缺点。

4

3 回答 3

1

有多种方法可以改变这种方法。请记住,没有解决方案本身真的是“错误的”。这一切都取决于您的具体情况。这是给猫剥皮的一种方法。

谁应该处理实体副本的创建?(主或细节)

我将 master 视为持久实体子集的内存列表表示。我会允许主人处理对其列表的任何更改。列表本身可以是自定义集合。使用 ItemChanged 事件向 master 发出通知,告知项目已更新并需要保留。触发 NewItem 事件以通知 master 插入。

我们使用 copyFrom() 来防止必须替换集合中的实体,这可能导致引用中断。有一个更好的方法吗?(实现 copyFrom() 可能很棘手)

我不会使用 copyFrom(),而是将现有引用传递给详细信息弹出窗口。如果您使用可枚举集合来存储主列表,则可以将从 list[index] 返回的对象传递到详细信息窗口。引用本身将被更改,因此无需在列表中使用任何类型的 Replace 方法。按下 OK 后,触发 ItemChanged 事件。您甚至可以传递索引,以便它知道要更新哪个对象。

新实体收到 -1 的 id(服务器层/休眠使用它来区分插入或更新)。在保存实体之前按 id 查找(缓存)实体时,这可能会导致问题。我们应该为每个新实体使用一个临时的唯一 id 吗?

更改不会立即持久化吗?使用带有工作单元模式的休眠会话来确定要插入什么以及要更新什么。还有更多工作单元的例子。如果 Java 端的内容不多,您可能需要查看 .NET 社区的一些博客文章。无论哪种方式,这个概念都是同一种动物。

希望这可以帮助!

于 2009-06-23T12:47:35.017 回答
0

CSLA 库可以帮助解决这种情况。

但是,如果您想自行实现:

您有一个主对象,主对象包含一个子对象列表。

详细表单可以直接编辑子对象。由于一切都是引用类型,因此主对象会自动更新。

问题是知道主对象是脏的,因此应该持久化到您的数据库或诸如此类的东西。

CSLA 使用 IsDirty() 属性处理此问题。在主对象中,您将查询每个子对象以查看它是否脏,如果是,则保留所有内容(以及跟踪主对象本身是否脏)

你也可以处理这个是 INotifyPropertyChanged 接口。

至于您的其他一些问题:

你想分离你的逻辑。实体可以处理其自身属性的存储,以及自身的完整性规则,但不同对象如何相互交互的逻辑应该是分开的。研究诸如 MVC 或 MVP 之类的模式。

在这种情况下,新子对象的创建应该在主对象中,或者应该在创建子对象然后将其添加到父对象的单独业务逻辑对象中。

对于 ID,使用 GUID 作为 ID 可以为您节省不少问题,因为这样您就不必与数据库对话来确定正确的 ID。您可以在对象上保留一个标志,以确定它是否是新的(因此应该插入或更新)。

同样,CSLA 为您处理所有这些,但确实有相当多的开销。

关于取消时的撤消:CSLA 实现了 n 级撤消,但如果您尝试手动操作,我会使用您的 CopyFrom 函数,或者在取消(重新获取)时从持久层刷新对象的数据。

于 2009-07-02T03:06:51.953 回答
0

我刚刚实现了这样一个模型。但没有使用 NH,我使用自己的代码将对象保存在 Oracle Db 中。

我在同一个 Web 表单中使用了主细节概念。

就像我有主实体网格和详细操作命令一样,我在单击的主记录行下方打开一个惩罚。

在详细信息添加模式下,我只是填充了一个空实体,其 id 由静态字段以负数生成。在保存详细信息按钮上,我将该实体保存在 Asp.NET 会话中主记录的详细信息列表中。

在详细信息编辑中,查看我使用 Jquery 通过 ajax 调用填充了详细信息面板,并在单击的行下方附加了该惩罚。

在保存按钮上,我将主会话(包含详细信息列表)保存在数据库中。

我工作得很好,好像大师需要填写多个细节。

如果您愿意,也可以使用 Jquery Modal 来弹出该面板,而不是附加到行下方。

希望它有帮助:)谢谢,

于 2010-01-19T19:08:19.927 回答