В чем разница между ISession.SaveOrUpdateCopy () и ISession.Merge ()? - PullRequest
6 голосов
/ 04 августа 2011

В NHibernate 3.1 ISession.SaveOrUpdateCopy() помечен как устаревший.В документации предлагается использовать Merge().Документация для каждого из них выглядит следующим образом:

SaveOrUpdateCopy(object obj)

Скопируйте состояние данного объекта в постоянный объект с тем же идентификатором.Если в данный момент нет постоянного экземпляра, связанного с сеансом, он будет загружен.Вернуть постоянный экземпляр.Если данный экземпляр не сохранен или не существует в базе данных, сохраните его и верните как новый постоянный экземпляр.В противном случае данный экземпляр не становится связанным с сеансом.

Merge(object obj)

Скопируйте состояние данного объекта в постоянный объект с тем же идентификатором.Если в данный момент нет постоянного экземпляра, связанного с сеансом, он будет загружен.Вернуть постоянный экземпляр.Если данный экземпляр не сохранен, сохраните копию и верните ее как новый постоянный экземпляр.Данный экземпляр не становится связанным с сеансом.Эта операция распространяется на связанные экземпляры, если сопоставление сопоставлено с cascade="merge".
Семантика этого метода определена JSR-220.

Они выглядят почти идентичными мне, но естьОбязательно должны быть некоторые тонкости.Если да, то что они?

1 Ответ

10 голосов
/ 04 августа 2011

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 ) одинаковы!

Глядя на списки слушателей, они оба инициализируются с прослушивателем по умолчанию. Прослушиватель по умолчанию для обработчиков прослушивания Merge имеет тип DefaultMergeEventListener , тогда как SaveOrUpdateCopy равен DefaultSaveOrUpdateCopyEventListener . Таким образом, разница между ними заключается только в разнице в этих двух реализациях (то есть, если вы сохраняете прослушиватель по умолчанию, что составляет 99% времени).

Однако, действительно интересный факт IS разница в реализации. Если вы посмотрите на DefaultSaveOrUpdateCopyEventListener , вы получите следующее:

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

Это означает, что поведение по умолчанию для Слияние и SaveOrUpdateCopy отличается только каскадными действиями, все остальное точно так же.

...