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