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 @   zhangweiwen  阅读(1974)  评论(1编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· [AI/GPT/综述] AI Agent的设计模式综述
点击右上角即可分享
微信分享提示