NHibernate: Как получить экземпляр сущности из кеша сессии?
Я начинаю сеанс в начале единицы работы и закрываю ее в конце. Единица работы распределяется по нескольким методам.
В одном методе я загружаю объект, используяGet
метод. Так что это сидит в кеше сессии. Экземпляр объекта является локальным для метода. Поэтому, когда заканчивается область действия метода, экземпляр сущности становится недоступным. Но сущность все еще находится в кеше сессии.
Теперь второй метод создает новый экземпляр объекта и пытается его удалить. Это кидаетNonUniqueObjectException
как и ожидалось.
Ниже приводится решение, которое я могу представить, но не могу реализовать:
public void Delete<T>(T instance) where T : BaseEntity
{
try
{
nhSession.Delete(instance);
}
catch(NonUniqueObjectException)
{
T instanceFromCache = GetInstanceFromCache<T>(instance);
nhSession.Evict(instanceFromCache);
nhSession.Delete(instance);
}
}
Если я могу каким-то образом получить экземпляр объекта из кэша сеанса, я могуEvict
это и, надеюсь, проблема будет решена. Но я не могу реализовать свои воображаемыеGetInstanceFromCache
метод.
Я пытался с помощьюnhSession.Get
, но это не помогает в моем сценарии. Имя столбца первичного ключа в моей базе данных НЕ "id", а также оно не одинаково для разных таблиц. В одной таблице это «Field1», а в другой - «Field2». Поэтому я не могу использовать что-то вродеnhSession.Get(instance.Id)
, мойDelete<T>(T instance)
Метод получает экземпляр объекта для удаления в качестве параметра. Он не получает значение первичного ключа для удаления.
Для получения дополнительной информации, пожалуйста, обратитесь мойДругой вопрос. Этот вопрос обсуждает проблему ОБНОВЛЕНИЯ и как я ее исправил; но сценарий похож
Редактировать 1Ответ «@Ricardo Peres» не работает как есть, но я немного изменил его код.
public static TEntity GetInstanceFromCache<TEntity>(this ISession nhSession, object instance) where TEntity : BaseEntity
{
var sessionImpl = nhSession.GetSessionImplementation();
foreach(BaseEntity baseEntity in sessionImpl.PersistenceContext.EntityEntries.Keys)
{
if(baseEntity is TEntity)
{
TEntity instanceFromCache = (TEntity)baseEntity;
if(nhSession.GetIdentifier(instanceFromCache) == nhSession.GetIdentifier(instance))
return baseEntity as TEntity;
}
}
return null;
}
ВызовnhSession.GetIdentifier(instance)
бросает исключениеTransientObjectException
(«Экземпляр не был связан с этим сеансом»), что ожидается. Это потому чтоinstance
неизвестноnhSession
, Любой способ получить идентификатор объекта, который не связан с сеансом?