Using session.Refresh
使用session.Refresh
特别是在桌面应用程序中,重新加载实体以反映她在不同会话中的新进修改,本节介绍如何使用session.Refresh来刷新同时被两个会话使用的实体数据.
准备
使用第一章的Eg.Core和第二章的Configuring NHibernate with App.config来创建一个控制台应用程序.
步骤
1. 在Main方法中添加如下代码:
var sessionA = sessionFactory.OpenSession(); var sessionB = sessionFactory.OpenSession(); Guid productId; Product productA; Product productB; productA = new Product() { Name = "Lawn Chair", Description = "Lime Green, Comfortable", UnitPrice = 10.00M }; using (var tx = sessionA.BeginTransaction()) { Console.WriteLine("Saving product."); productId = (Guid) sessionA.Save(productA); tx.Commit(); } using (var tx = sessionB.BeginTransaction()) { Console.WriteLine("Changing price."); productB = sessionB.Get<Product>(productId); productB.UnitPrice = 15.00M; tx.Commit(); } using (var tx = sessionA.BeginTransaction()) { Console.WriteLine("Price was {0:c}", productA.UnitPrice); sessionA.Refresh(productA); Console.WriteLine("Price is {0:c}", productA.UnitPrice); tx.Commit(); } sessionA.Close(); sessionB.Close(); Console.ReadKey();
2. 编译运行,结果如下图所示:
原理
在这个刻意的示例中,我们打开了两个会话来操作同一实体的两个实例.在会话A中,保存了一个新建的产品:价格为$10的"lime green lawn chair ".在会话B中,我们获取了同一个"lawn chair".现在有了同一实体的两个实例.一个同会话A相关联,一个同会话B相关联.
我们将会话B中的lawn chair的价格修改为$15.请注意,我们没有调用任何方法来将修改保存或更新到数据库.由于会话B加载了该"lawn chair",所以她会跟踪修改,并在会话刷新的时候自动更新数据库.这在提交事务的时候自动发生,这种情况呗称为自动脏校验.会话A中"lawn chair"的实例价格仍然是$10.
调用sessionA.Refresh后,NHibernate会用数据库中的新数据来更新会话A中的"lawn chair"的数据.现在会话A中的"lawn chair"的新价格是$15.
扩展
session.Refresh在多会话桌面应用程序中特别重要,这样的程序可能有几个会话在同时运行以处理多个数据表单,而且对表单的修改保存后要求及时反映到使用同一实体的另一个表单
在这样的场景中,你很可能会在表单之间设立某种形式的消息来发布,以便通知使用同一个实体的其他表单,"该实体已经被保存".当表单收到这样的一个消息后,她会调用session.Refresh来获取新数据I.