这似乎是一个常见问题,但我不知道解决问题的最佳方法。我希望能够向视图发送实体,在视图中对实体进行更改,但如果用户取消视图,则取消(删除)这些更改。这样做的正确方法是什么。
我有两个选项,但我认为应该有更好的其他选择
1)获取实体,创建克隆,将克隆发送到视图...如果接受更改,则使用克隆值更新原始实体
2)将实体发送到视图,如果用户取消,则从NHibernate的缓存中删除实体并从数据库重新加载
对于(2),我的问题是,在从缓存中删除旧实体后,仍然可以在整个项目中引用旧实体。
修改
好的,如果我正在实现方法(2),那么evict方法就是这样。谢谢,我不记得那个细节了。但是,引用旧的被逐出实体的视图对象的问题使得该问题难以处理。我不能让我的视图自动更新到新实体,而不会在我的自定义驱逐事件被引发时在每个实体中都有自定义代码重新绑定。在某些情况下,重新绑定可能并非微不足道。我需要更多地考虑这个问题,因为我可能会过于复杂,但目前这种方法看起来比较棘手。
我怀疑我会遇到方法(1),它有自己的问题,但会等待一段时间,看看是否有其他人有想法。
编辑2 :刚发现这个。我认为它几乎涵盖了详细的答案,并附带了一个很棒的演示项目 - 使用NHibernate构建桌面待办事项 - http://msdn.microsoft.com/en-us/magazine/ee819139.aspx
除此之外, NHibernate有一个Session.Refresh(对象实体)函数,这似乎解决了确切的问题。因此,当一个实体被更改但在保存之前被取消时,我可以调用Session.Refresh从数据库重新加载它并丢弃更改。
答案 0 :(得分:1)
执行此操作的最佳方法是在用于加载对象的Evict
上调用ISession
方法。这将从会话缓存中删除该对象。然后你可以重新加载并重新显示它。
从会话中删除对象使其 transient 分离,因此如果项目中仍有对它的引用,则在刷新会话时不会保留它们。你如何处理这个问题取决于你的应用程序,但我建议你提出一个事件来通知订阅者他们需要重新加载这个对象。
答案 1 :(得分:1)
我将选择选项1并使用所谓的ViewModel而不是您的实体。 ViewModel表示您为特定视图建模的模型。在ViewModel中,您可以混合来自不同实体的数据并预先格式化值以适合视图。是一种将数据传递到视图的优雅方式,您可以轻松地完成您想要的任务。
使用ViewModels正成为在ASP.net MVC和Silverlight / WPF中工作的首选方式。
要详细了解Viewmodels:http://blogs.msdn.com/dphill/archive/2009/01/31/the-viewmodel-pattern.aspx