迷恋弦哥

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

Using session.Merge

使用session.Merge

  session.Merge可能是NHibernate中最被误解的特性之一.本节介绍如何使用session.Merge将一个脏的独立的实体和一个新的会话合并. 这在从StaleObjectStateExceptions恢复时特别有用.

准备

  使用第一章的Eg.Core和第二章的Configuring NHibernate with App.config来创建一个控制台应用程序.

步骤

1.   在Main方法中添加如下代码:

View Code
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);
    tx.Commit();
    // Returns false
    ReferenceEquals(book, mergedBook);
  }
}

2.   添加CreateAndSaveBook方法,代码如下:

View Code
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();
      session.Evict(book);
    }
  }
  return book;
}

 

原理

  在CreateAndSaveBook方法中,新建了一个book并将它保存到了数据库.提交我们的事务,将该book从会话中剔除,关闭会话并将该book返回. 问题来了,现在有个和会话无关的实体,无法检测该实体的变化,她只是一个普通的book对象.
  我们修改了该book对象,并且想要保存这些修改.但是NHibernate不知道我们对该book对象的操作. 她已经可以穿过其他层或大型应用程序中的不同层.我们不知道她和哪个会话关联,我们甚至不知道该book在数据库中是否存在.
  Session.Merge会为我们处理所有这些不确定性.如果当前的会话中有该ID的book,那么该book的数据就会被复制到会话中的可持久化的book对象,并且可持久化的book对象会被返回.
  如果当前会话中没哟该ID的book,NHibernate会从数据库中加载她.这些修改会被复制到刚加载到会话中的可持久化book对象.该可持久化的book对象会被返回.
  如果NHibernate在数据库中也找不到该ID的book,NHibernate会将该book的数据复制到一个新的和会话关联的可持久化book对象,并返回这个新的可持久化book对象.
  session.Merge的最终结果是相同的.返回的book对象和传入的book对象时不同的实例,但她包含了我们所做的所有修改并且她被关联到了当前会话.提交事务后,这些修改都会被写入数据库.
  我们开始传入的book对象和当前会话是不关联的.

posted on 2012-07-15 11:30  迷恋弦哥  阅读(229)  评论(0编辑  收藏  举报