NHibernate: есть ли способ пометить объект как НЕ грязный? - PullRequest
1 голос
/ 29 октября 2009

У меня есть ситуация, когда мне нужно загрузить часть графа объектов, используя пользовательский SQL (по соображениям производительности). Поэтому я загружаю эту коллекцию, используя свой собственный SQL (ISession.CreateSQLQuery ()), а затем назначаю этот список свойству другого объекта-сущности.

Проблема в том, что когда я присваиваю свойству список, это загрязняет эту сущность вместе со всеми объектами в списке, поэтому, когда я собираюсь сохранить объект, он выполняет сотни запросов, чтобы сохранить весь список , Есть ли способ, которым я могу указать, что объект НЕ грязный (после того, как я сам его загрузил)?

(Да, я знаю, что могу отключить cascade = "save-update", но я действительно не хочу этого делать, если я могу избежать этого.)

Ответы [ 6 ]

3 голосов
/ 29 октября 2009

Я думаю, что есть возможность выселить сущность.

Это означает, что он больше не подключен к NHibernate.


ОБНОВЛЕНО после различных комментариев Джона:

  • Если вы хотите, чтобы NHibernate управлял объектом, т. Е. Определял, не загрязнен ли он, сохраняйте управление им.
  • Если нет, Evict () это, это не будет управляться. Вы все еще можете сохранить его вручную и т. Д., Просто это не будет сделано автоматически для вас.

Я не вижу никакого среднего уровня, между автоматическим и ручным ...

Обратите внимание, что вы по-прежнему можете сохраняться различными способами, например сохранять вручную родительский объект, набор дочерних объектов и т. Д. ... Многие вещи все еще возможны.

2 голосов
/ 29 октября 2009

Расширяя ответ KLE, я бы:

  1. Evict () родительский объект
  2. Загрузить список детей
  3. Прикрепить список детей к родительской сущности
  4. Объединить () все это обратно в nHibernate

В этот момент я верю, что NHibernate распознает все как чистое.

1 голос
/ 29 октября 2009

Если вы не сохраняете свойство, которому назначен список, вы можете удалить это свойство из сопоставления NHibernate. Я не проверял это, но я ожидаю, что присвоение этого свойства не приведет к тому, что IsDirty () вернет true.

РЕДАКТИРОВАТЬ: Хорошо, попробуйте попробовать это. Загрузите объект из IStatelessSession, вызовите пользовательский SQL и назначьте свойство. Затем заблокируйте объект в новой ISession и продолжайте работать с ним. Я думаю, что блокировка будет каскадно подключаться к дочерним объектам, если в настройках каскада установлено значение all или all-delete-orphan. Если блокировка не происходит каскадно, вам придется вручную обходить граф объектов.

1 голос
/ 29 октября 2009

Можете ли вы просто удалить свойство, которое вы используете для хранения этих данных, извлеченных вручную, из отслеживания NHibernates?

0 голосов
/ 23 июля 2015

Не помню, откуда я это взял, но у меня есть класс расширений Session, одним из которых является:

public static Object GetOriginalEntityProperty(this ISession session, Object entity, String propertyName)
{

    ISessionImplementor sessionImpl = session.GetSessionImplementation();

    IPersistenceContext persistenceContext = sessionImpl.PersistenceContext;

    EntityEntry oldEntry = persistenceContext.GetEntry(entity);



    if ((oldEntry == null) && (entity is INHibernateProxy))
    {

        INHibernateProxy proxy = entity as INHibernateProxy;

        Object obj = sessionImpl.PersistenceContext.Unproxy(proxy);

        oldEntry = sessionImpl.PersistenceContext.GetEntry(obj);

    }

    if (oldEntry == null)  // I'm assuming this means the object is transient and that this is the way to treat that
        return false;

    String className = oldEntry.EntityName;

    IEntityPersister persister = sessionImpl.Factory.GetEntityPersister(className);

    Object[] oldState = oldEntry.LoadedState;

    Object[] currentState = persister.GetPropertyValues(entity, sessionImpl.EntityMode);

    Int32[] dirtyProps = persister.FindDirty(currentState, oldState, entity, sessionImpl);

    Int32 index = Array.IndexOf(persister.PropertyNames, propertyName);



    Boolean isDirty = (dirtyProps != null) ? (Array.IndexOf(dirtyProps, index) != -1) : false;



    return ((isDirty == true) ? oldState[index] : currentState[index]);

}

Если вы получите исходное значение с помощью этого метода и присвоите его постоянному свойству, оно больше не будет грязным.

0 голосов
/ 12 августа 2010

Вы можете использовать перехватчик, а затем переопределить метод FindDirty.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...