我想知道人们在主从细节设置中使用什么策略来处理实体的创建和编辑。 (我们的应用是支持互联网的桌面应用。)
以下是我们当前处理此问题的方法:在弹出窗口中为需要编辑的实体创建表单,我们提供该对象的副本。当用户单击“取消”按钮时,我们关闭窗口并完全忽略该对象。当用户单击“确定”按钮时,将通知主视图并接收已编辑的实体。然后,它使用originalEntity.copyFrom(modifiedEntity)将修改后的实体的属性复制到原始实体中。如果我们想要创建一个新实体,我们将一个空实体传递给弹出窗口,然后用户可以编辑该窗口,就好像它是一个现有实体一样。主视图需要决定是将其接收的实体“插入”或“更新”到它管理的集合中。
我对上述工作流程有一些问题和意见:
任何人都可以分享提示&技巧或经历?谢谢!
编辑:我知道这个问题没有绝对的错误或正确的答案,所以我只是在寻找人们在处理主人/细节情况的方式上分享想法和利弊
答案 0 :(得分:1)
您可以通过多种方式改变这种方法。请记住,没有任何解决方案本身可能真的“错误”。这一切都取决于你的情况的细节。这是给猫皮肤的一种方法。
谁应该处理实体副本的创建? (主人或细节)
我将master视为持久化实体子集的内存列表表示。我会允许主人处理其列表的任何更改。列表本身可以是自定义集合。使用ItemChanged事件向主服务器发出通知,表明项目已更新且需要保留。触发NewItem事件以通知主控器插入。
我们使用copyFrom()来防止必须替换集合中可能导致引用中断的实体。有一个更好的方法吗? (实现copyFrom()可能很棘手)
我不会使用copyFrom(),而是将现有引用传递给详细信息弹出窗口。如果您使用可枚举集合来存储主列表,则可以将list [index]返回的对象传递给详细信息窗口。引用本身将被更改,因此不需要在列表中使用任何类型的Replace方法。按下确定后,触发ItemChanged事件。您甚至可以传递索引,以便知道要更新的对象。
新实体接收的id为-1(服务器层/ hibernate用于区分插入或更新)。在保存之前,通过id查找(缓存)实体时,这可能会导致问题。我们应该为每个新实体使用临时唯一ID吗?
更改是否仍未立即生效?使用Hibernate Session with the Unit of Work pattern确定要插入的内容和正在更新的内容。那里有更多工作单位的例子。如果Java端没有太多内容,您可能需要查看.NET社区的一些博客文章。无论如何,这个概念都是同一种动物。
希望这有帮助!
答案 1 :(得分:0)
CSLA图书馆可以帮助解决这个问题。
但是,如果你想自己实现:
您有一个主对象,主对象包含一个子对象列表。
详细信息表单可以直接编辑子对象。由于所有内容都是引用类型,因此主对象会自动更新。
问题是知道主对象是脏的,因此应该持久保存到您的数据库或诸如此类。
CSLA使用IsDirty()属性处理此问题。在主对象中,您将查询每个子对象以查看它是否为脏,如果是,则保留所有内容(以及跟踪主对象本身是否为脏)
您也可以处理这是INotifyPropertyChanged界面。
至于你的其他一些问题:
你想分开你的逻辑。实体可以处理自己的属性的存储,以及自身的完整性规则,但是不同对象如何相互交互的逻辑应该是分开的。研究MVC或MVP等模式。
在这种情况下,创建新的子对象应该在主对象中,或者应该在创建子对象的单独业务逻辑对象中,然后将其添加到父对象。
对于ID,使用GUID作为ID可以为您节省相当多的问题,因为这样您就不必与数据库通信以确定正确的ID。如果对象是新的(或因此应该插入或更新),您可以在对象上保留一个标记。
同样,CSLA会为您处理所有这些,但确实会有相当多的开销。
关于取消时撤消:CSLA实现了n级撤销,但是如果你试图手动执行,我会使用你的CopyFrom函数,或者在取消时从persistance层刷新对象的数据(重新获取) )。
答案 2 :(得分:0)
我刚刚实现了这样的模型。但是没有使用NH,我使用自己的代码来持久化Oracle Db中的对象。
我在同一网页表格中使用了主细节概念。
就像我有主实体网格和详细动作命令一样,我在点击的主记录行下方打开一个惩罚。
在详细信息添加模式下,我只填充一个空实体,其id由静态字段生成负数。在保存详细信息按钮上,我将该实体保存在Asp.NET会话中主记录的详细信息列表中。 / p>
在详细信息编辑中,视图i使用Jquery通过ajax调用使用选定的详细信息填充详细信息面板,并在单击的行下方附加该惩罚。
在保存按钮上,我将主会话(包含详细信息列表)保存在数据库中。
我的工作对我好,好像主人需要填写的多个细节。
如果你愿意,也可以使用Jquery Modal来弹出Panel而不是在行下方附加。
希望有帮助:) 谢谢,