ISession.SaveOrUpdateCopy()和ISession.Merge()有什么区别?

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

SaveOrUpdateCopy(object obj)

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

Merge(object obj)

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

它们看起来几乎一样,但肯定存在一些微妙之处。如果有的话,它们是什么?
1个回答

10

SaveOrUpdateCopy现在已被认为是过时的,因此Merge被视为其继任者(因此它们非常相似)。

它们几乎完全相同,除了我不认为SaveOrUpdateCopy具有级联选项。然而,这一点已经无关紧要了,因为应该使用Merge方法。


更新:我进入NHibernate的源代码,确保它们是我所想象的那样相似,以下是我的发现。

MergeSaveOrUpdateCopy都有非常相似的实现:

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,而 SaveOrUpdateCopy 则为 DefaultSaveOrUpdateCopyEventListener。因此,它们之间的差异只是这两个实现之间的差异(假设您保留默认监听器,这通常占99%的时间)。

然而,真正有趣的事实其实是实现的不同。如果您查看 DefaultSaveOrUpdateCopyEventListener,您会得到以下内容:

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

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接