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)も同じです。
リスナーリストを見ると、どちらもデフォルトのリスナーで初期化されています。マージリッスンハンドラーのデフォルトリスナーはDefaultMergeEventListenerタイプで、SaveOrUpdateCopyはDefaultSaveOrUpdateCopyEventListenerです。したがって、これらの違いは、これら2つの実装の違いにすぎません(つまり、デフォルトのリスナー(99%の時間)を維持する場合)。
ただし、実際に興味深いのは、実装の違いです。DefaultSaveOrUpdateCopyEventListenerを見ると、次のようになります。
public class DefaultSaveOrUpdateCopyEventListener : DefaultMergeEventListener
{
protected override CascadingAction CascadeAction
{
get { return CascadingAction.SaveUpdateCopy; }
}
}
つまり、 MergeとSaveOrUpdateCopyのデフォルトの動作は、カスケードアクションのみが異なり、他のすべてはまったく同じです。