6

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

SaveOrUpdateCopy(object obj)

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

Merge(object obj)

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

它们看起来和我几乎一模一样,但肯定会有一些微妙之处。如果是这样,它们是什么?

4

1 回答 1

10

SaveOrUpdateCopy现在被认为是过时的,因此Merge旨在接管它(因此它非常相似)。

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


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

Merge和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 ) 也是相同的!

查看侦听器列表,它们都使用默认侦听器进行了初始化。Merge侦听处理程序的默认侦听器是DefaultMergeEventListener类型,而SaveOrUpdateCopyDefaultSaveOrUpdateCopyEventListener。因此,它们之间的区别只是这两种实现方式的区别(也就是说,如果您保留默认侦听器,即 99% 的时间)。

然而,真正有趣的事实实现方式的不同。如果你看一下DefaultSaveOrUpdateCopyEventListener你会得到这个:

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

这意味着MergeSaveOrUpdateCopy的默认行为仅在级联操作上有所不同,其他一切都完全相同。

于 2011-08-04T17:29:32.573 回答