ISession.SaveOrUpdate Copy()和Session.Merge()有什么区别?

时间:2011-08-04 14:49:11

标签: nhibernate nhibernate-3

在NHibernate 3.1中,ISession.SaveOrUpdateCopy()已被标记为已弃用。文档建议使用Merge()代替。每个文件如下:

SaveOrUpdateCopy(object obj)

  

将给定对象的状态复制到具有相同标识符的持久对象上。如果当前没有与之关联的持久性实例   会话,它将被加载。返回持久化实例。如果   给定实例未保存或数据库中不存在,保存并保存   将其作为新的持久化实例返回。否则,给定的实例   与会话无关。

Merge(object obj)

  

将给定对象的状态复制到具有相同对象的持久对象上   标识符。如果当前没有与之关联的持久性实例   会话,它将被加载。返回持久化实例。如果   给定实例未保存,保存副本并将其作为新持久化返回   实例。给定的实例不会与会话关联。   如果映射关联,则此操作级联到关联的实例   与cascade="merge"
  此方法的语义由JSR-220定义。

他们看起来几乎与我相同,但必然会涉及一些细微之处。如果是这样,他们是什么?

1 个答案:

答案 0 :(得分:10)

SaveOrUpdateCopy 现在被认为是过时的,因此合并意味着接管它(因此它的极端相似性)。

它们几乎相同,只是我认为这些级联选项不适用于 SaveOrUpdateCopy 。但是,这一点没有实际意义,因为合并应该是您使用的方法。


更新:我进入NHibernate的源代码只是为了确保它们和我想的一样相似,这就是我找到的。

合并 SaveOrUpdateCopy 都有非常相似的实现:

public object Merge(string entityName, object obj)
{
    using (new SessionIdLoggingContext(SessionId))
    {
        return FireMerge(new MergeEvent(entityName, obj, this));
    }
}

public object SaveOrUpdateCopy(object obj)
{
    using (new SessionIdLoggingContext(SessionId))
    {
        return FireSaveOrUpdateCopy(new MergeEvent(null, obj, this));
    }
}

他们的 FireXXXX 方法也非常相似:

private object FireMerge(MergeEvent @event)
{
    using (new SessionIdLoggingContext(SessionId))
    {
        CheckAndUpdateSessionStatus();
        IMergeEventListener[] mergeEventListener = listeners.MergeEventListeners;
        for (int i = 0; i < mergeEventListener.Length; i++)
        {
            mergeEventListener[i].OnMerge(@event);
        }
        return @event.Result;
    }
}

private object FireSaveOrUpdateCopy(MergeEvent @event)
{
    using (new SessionIdLoggingContext(SessionId))
    {
        CheckAndUpdateSessionStatus();
        IMergeEventListener[] saveOrUpdateCopyEventListener = listeners.SaveOrUpdateCopyEventListeners;
        for (int i = 0; i < saveOrUpdateCopyEventListener.Length; i++)
        {
            saveOrUpdateCopyEventListener[i].OnMerge(@event);
        }
        return @event.Result;
    }
}

方法完全相同,只是它们在不同的事件监听器列表上绘制,但即使列表的类型( IMergeEventListener )也是相同的!

查看侦听器列表,它们都使用默认侦听器进行初始化。 合并侦听处理程序的默认侦听器类型为 DefaultMergeEventListener ,而 SaveOrUpdateCopy DefaultSaveOrUpdateCopyEventListener 。因此,它们之间的差异只是这两种实现的差异(即如果你保留默认监听器,这是99%的时间)。

然而,真正有趣的事实 IS 实施的差异。如果你看一下 DefaultSaveOrUpdateCopyEventListener ,你会得到这个:

public class DefaultSaveOrUpdateCopyEventListener : DefaultMergeEventListener
{
    protected override CascadingAction CascadeAction
    {
        get { return CascadingAction.SaveUpdateCopy; }
    }
}

这意味着合并 SaveOrUpdateCopy 的默认行为仅在级联操作中有所不同,其他所有内容都完全相同。