NHibernate使用session.Merge[翻译]

NHibernate 3.0 Cookbook第三章,使用session.Merge的翻译.

session.Merge也许是NHibernate最容易被误解的特性之一.这里我会展示怎么使用一个新的Session的session.Merge来关联一个脏的,游离的实体.这个方法可以非常便利的从StaleObjectStateExceptions中恢复.

准备

使用第一章的Eg.Core的model同时使用App.config配置NHibernate,建立一个控制台应用程序.

怎样做

把下面代码添加到你的主方法里.

        static void Main(string[] args) {
            log4net.Config.XmlConfigurator.Configure();
            var nhConfig = new Configuration().Configure();
            var sessionFactory = nhConfig.BuildSessionFactory();

            var book = CreateAndSaveBook(sessionFactory);
            book.Name = "Dormice in Action";
            book.Description = "Hibernation of the Hazel Dormouse";
            book.UnitPrice = 0.83M;
            book.ISBN = "0123";

            using (var session = sessionFactory.OpenSession()) {
                using (var tx = session.BeginTransaction()) {
                    var mergedBook = (Book)session.Merge(book);
                    // Returns false
                    Console.WriteLine(ReferenceEquals(book, mergedBook));
                    tx.Commit();
                }
            }
        }

添加一个CreateAndSaveBook方法:

       private static Book CreateAndSaveBook(ISessionFactory sessionFactory) {
            var book = new Book() {
                Name = "NHibernate 3.0 Cookbook",
                Description = "Pure Awesome.",
                UnitPrice = 50.0M,
                ISBN = "3043",
                Author = "Jason Dentler",
            };

            using (var session = sessionFactory.OpenSession()) {
                using (var tx = session.BeginTransaction()) {
                    session.Save(book);
                    tx.Commit();
                }
            }
            return book;
        }

原理

在CreateAndSaveBook方法里,我们新建了一个Book对象同时保存到数据库,我们提交了事务,Book对象脱离了Session,关闭Session,和返回这个book对象.这样就建立了我们的问题.现在我们有一个脱离了Session的实体.这个实体的改变不会被跟踪.它只是一个简单的普通的对象.

我们继续改变这个book对象,现在我们想保存这些变化.NHibernate不知道我们对这个book对象做了什么.它可能被传递到应用程序的其它层.即使有的话,我们也不知道它与那个Session有关联.我们甚至不知道这个book对象在数据库是否存在.

Session.Merge为我们处理所有这些不确定性.如果当前的Session有这个ID的book对象,我们的book对象的数据会复制给这个Session的一个持久态的book对象,返回这个持久态book对象.

如果当前的Session没有这个Id的book对象,NHibernate会从数据库中加载它.数据的变化会被复制给刚刚加载的那个持久态对象,返回这个持久态book对象.

如果NHibernate在数据库中没有找到这个ID的book对象,会复制我们book对象的数据给一个与这个Session关联的持久态对象,返回这个新的持久态对象.

session.Merge最后的结果都是相同的.返回的Book与我们传递进去的不是一个实例,但它包含我们所有的变化和它是与当前的Session关联的.当我们提交事务,这些变化会被写到数据库.

我们传入的Book对象与当前Session是没有关联的.

posted @ 2011-11-18 17:51  zhangweiwen  阅读(1973)  评论(1编辑  收藏  举报