Все знают, что в сессии есть кеш.Этот кэш обычно можно очистить двумя способами:
- Session.Evict
- 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.Но мне кажется, не очень хорошая идея дублировать код.Может быть, у кого-то есть другие идеи?