Как обнаружить изменения коллекции в NHibernate - PullRequest
1 голос
/ 29 июня 2011

Как я могу обнаружить изменения (добавления и удаления) из множества наборов и списков в NHibernate?

Я использую перехватчик для обнаружения изменений в объектной модели (для аудита и т. Д.), Этоотлично работает для изменений в объекте (используя OnSave / OnFlushDirty), но не для коллекций.

Когда изменяется коллекция, вызывается метод OnCollectionUpdate, но он получает только ключ объекта, содержащего коллекцию, и последние элементы коллекции.

Что мне нужно:

  1. объект, содержащий коллекцию (или, по крайней мере, тип + ключ, ключ уникален только внутри класса в моей системе), я толькоесть ключ сейчас.

  2. имя свойства коллекции (у меня есть классы с несколькими коллекциями)

  3. Список добавленных элементов и список удаленных элементов (или, альтернативно, содержимое коллекции до и после текущей транзакции).

Есть ли способ получить эту информацию?

Ответы [ 4 ]

1 голос
/ 27 сентября 2012

Если вы не переопределяете стандартную коллекцию nhibernate (список, набор, карта), вы всегда можете получить начальный контент коллекции (контент, который был сохранен в базе, до каких-либо изменений).Пример для списков:

PersistentList c = myCollection as PersistentList;
if ((c == null)||(!c.IsDirty)) {
        return;
}
IEnumerable storedCollection = c.StoredSnapshot as IEnumerable;
if ((storedCollection == null)) {
        return; //looks like a error
}
foreach(var element in storedCollection) {
     //do something with old items
}
foreach(var element in storedCollection) {
     //do something with new items
}

Конечно, вы можете определить, какие элементы были добавлены, удалены или остались без изменений.

1 голос
/ 28 июля 2011

Я сейчас работаю над этим сам. Я еще не разобрался с твоим третьим вопросом (хотя я пытаюсь выяснить это), но это должно помочь тебе в твоем пути с № 1 и № 2:

public static void SomeMethod(this ISession session, object entity)
{            
    //this will give you the information about your entity
    String className = NHibernateProxyHelper.GuessClass(entity).FullName;
    ISessionImplementor sessionImpl = session.GetSessionImplementation();
    IEntityPersister persister = sessionImpl.Factory.GetEntityPersister(className);

    //at this point you can use the persister object to retrieve the info you need:

    //this gives you all properties and their values
    Object[] currentState = persister.GetPropertyValues(entity, sessionImpl.EntityMode);

    //this will return the types:
    IType[] typeArray = persister.PropertyTypes;

    //each IType object has a IsCollectionType bool which tells you if it is a collection:
    bool isCollection = IType[0].IsCollectionType;
}
0 голосов
/ 03 августа 2012

Это , а не код NHibernate (это код Hibernate Java), но поиск в Google NHibernate API делает его похожим, что вы могли бы начать работу и для NHibernate (есть класс PersistentMap, которыйимеет свойство Owner и свойство CollectionSnapshot):

public void onCollectionUpdate(Object collection, Serializable id) {
    System.out.println("****onCollectionUpdate");

    if(collection instanceof PersistentMap) {
        PersistentMap newValues = (PersistentMap) collection;
        Object owner = newValues != null ? newValues.getOwner() : null;
        Set<?> oldValues = newValues != null
            ? ((Map<?, ?>) newValues.getStoredSnapshot()).keySet()
            : null;

        System.out.println("owner: " + (owner != null ? owner.toString() : "(null)"));
        System.out.println("oldValues: " + (oldValues != null ? oldValues.toString() : "(null)"));
        System.out.println("newValues: " + (newValues != null ? newValues.toString() : "(null)"));
    } else if (collection instanceof PersistentSet) {
        PersistentSet newValues = (PersistentSet) collection;
        Object owner = newValues != null ? newValues.getOwner() : null;
        Set<?> oldValues = newValues != null
            ? ((Map<?, ?>) newValues.getStoredSnapshot()).keySet()
            : null;

        System.out.println("owner: " + (owner != null ? owner.toString() : "(null)"));
        System.out.println("oldValues: " + (oldValues != null ? oldValues.toString() : "(null)"));
        System.out.println("newValues: " + (newValues != null ? newValues.toString() : "(null)"));
    }
}

Обратите внимание, что я знаю, что это не код C # или NHibernate.Пожалуйста, прокомментируйте, если это абсолютно бесполезно для NHibernate (если API совсем не похож, хотя мой поисковый запрос говорит, что он похож), и я удалю пост.

Я погружен в землю Javaпрямо сейчас, или я бы попробовал это для вас:)

0 голосов
/ 29 июня 2011

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

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