NHibernate выселить по id

Все знают, что в сессии есть кеш. Этот кеш обычно можно очистить двумя способами:

  1. Session.Evict
  2. Session.Clear

Второй метод удаляет весь кеш не только для одной записи.

У меня есть бизнес-метод. Он получает идентификатор большого объекта (с сайта aspx) или иногда несколько идентификаторов. И выполните встроенную операцию sql в базе данных (используя sql-запрос со сложной логикой, чтобы не загружать все данные в C #). Затем мне нужно сделать кеш недействительным. Таким образом, каждая потенциальная загрузка объекта идет без кеширования прямо из базы данных.

К сожалению, выселить, принимая только объекты. Также его реализация DefaultEvictEventListener имеет четкое разделение пути кода - отдельно для прокси и не проксируемых классов. Я попытался просто создать объект, заполнить идентификатор вручную и передать его в Evict. Это не сработает. Насколько я понимаю, Evict не проксируемым классом использует GetHashCode для поиска и удаления объекта из кеша. Поэтому, если я не отменяю его, это не сработает. У меня много встроенных пакетных операций sql, поэтому переопределение всего GetHashcode во всех объектах сущностей создаст много работы. Также я не уверен, удаляет ли этот случай прокси из кеша или нет. Обновление: Насколько я ни пытался, переопределение GetHashCode также не помогло. StatefulPersistenceContext.RemoveEntry не найден, поскольку он использует RuntimeHelpers.GetHashCode. Так что это решение даже невозможно

Используя исходные коды NHibernate, я создал следующее решение:

public static class NHSessionHelper: DefaultEvictEventListener
 public static void RemoveEntityFromCache(this ISession session, Type type, object entityId)
    {
        ISessionImplementor sessionImpl = session.GetSessionImplementation();
        IPersistenceContext persistenceContext = sessionImpl.PersistenceContext;
        IEntityPersister persister = sessionImpl.Factory.GetEntityPersister(type.FullName);

        if (persister == null)
        {
            return;
        }

        EntityKey key = new EntityKey(entityId, persister, sessionImpl.EntityMode);
        persistenceContext.RemoveProxy(key);

        object entity = persistenceContext.RemoveEntity(key);
        if (entity != null)
        {
            EntityEntry e = persistenceContext.RemoveEntry(entity);
            DoEvict(entity, key, e.Persister, (IEventSource)sessionImpl);
        }
    }

Оно просто использует часть реализации NHibenate. Но мне кажется, что дублировать код - не лучшая идея. Может быть у кого-нибудь есть другие идеи?

6
задан Donal Fellows 5 November 2010 в 15:30
поделиться