NHibernate: Como obter uma instância de entidade do cache da sessão?

Inicio a sessão no início da unidade de trabalho e fecho no final da mesma. A unidade de trabalho é dividida em vários métodos.

Em um método, eu carrego a entidade usandoGet método. Portanto, isso fica no cache da sessão. A instância da entidade é local para o método Portanto, quando o escopo do método termina, a instância da entidade não está acessível. Mas a entidade ainda está no cache da sessão.

Agora, o segundo método cria uma nova instância da entidade e tenta excluí-la. Isso jogaNonUniqueObjectException como esperado.

A seguir está a solução que eu posso imaginar, mas não capaz de implementar:

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);
    }
}

Se eu conseguir obter a instância da entidade do cache da sessão de alguma forma, possoEvict e espero que o problema seja resolvido. Mas eu não sou capaz de implementar meu imaginárioGetInstanceFromCache método.

Eu tentei usarnhSession.Get, mas isso não é útil no meu cenário. O nome da coluna da chave primária no meu banco de dados NÃO é "id" e também não é o mesmo nas tabelas. Em uma tabela, é "Campo1" e em outra é "Campo2". Então não posso usar algo comonhSession.Get(instance.Id). MinhasDelete<T>(T instance) O método recebe uma instância da entidade para excluir como parâmetro. Ele não recebe o valor da chave primária a ser excluída.

Para mais informações, consulte o meude outros Pergunta, questão. Essa pergunta discute o problema UPDATE e como o corrigi; mas o cenário é semelhante.

Editar 1

Responder por "@Ricardo Peres" não funciona como está, mas modifiquei um pouco o código dele.

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;
}

A chamadanhSession.GetIdentifier(instance) lança uma exceçãoTransientObjectException ("A instância não foi associada a esta sessão"), o que é esperado. Isto é porqueinstance é desconhecido paranhSession. Alguma maneira de obter o identificador da entidade que NÃO está associada à sessão?

questionAnswers(2)

yourAnswerToTheQuestion