Pergunta

Eu estou usando um personalizado nomeado consulta com NHibernate que eu quero retornar uma coleção de objetos Person. O objeto Person não está mapeada com um mapeamento NHibernate que significa que eu estou recebendo a seguinte exceção:

System.Collections.Generic.KeyNotFoundException: A chave fornecida não estava presente no dicionário.

É ser jogado quando a sessão é criado porque não pode encontrar o nome da classe quando ele chama NHibernate.Cfg.Mappings.GetClass (String className). Isso tudo é bastante compreensível, mas eu queria saber se havia alguma maneira de dizer NHibernate para usar a classe mesmo que eu não tenho um mapeamento para ele?

Foi útil?

Solução 5

Para resolver isso, eu acabei usando o TupleToPropertyResultTransformer e fornecer a lista de valores de propriedade. Existem algumas limitações a este, sendo a principal delas que a consulta SQL deve retornar os resultados na mesma ordem que você fornecer seus propriedades para o construtor TupleToPropertyResultTransformer.

Além disso, os tipos de propriedade são inferidos por isso você precisa ter cuidado com colunas decimais retornando somente inteiro valores etc. Além de que o uso da TupleToPropertyResultTransformer forneceu uma maneira razoavelmente fácil de usar uma consulta SQL para retornar uma coleção de objetos sem o mapeamento explicitamente a objetos dentro NHibernate.

Outras dicas

Por que você não usar:

query.SetResultTransformer(Transformers.AliasToBean(typeof(Person)));

Ele irá inserir os dados de cada coluna na sua consulta em propriedades objeto pessoa usando alias de coluna como um nome da propriedade.

Como você pode criar uma consulta que retornaria instâncias de um tipo que não está mapeado?

Eu acho Michal tem um ponto aqui, e talvez você deve ter um olhar para projeções. (Pelo menos, é isso que eu acho que você está procurando).

Você cria uma consulta em algum tipo mapeada, e em seguida, você pode 'projecto' que consulta a um 'DTO'. A fim de fazer isso, você terá que 'importação' sua classe Pessoa, para que ele é conhecido por NHibernate, e você terá que usar um ResultTransformer.

Algo parecido com isto:

ICriteria crit = session.CreateCriteria (typeof(Person));

// set some filter criteria

crit.SetProjection (Projections.ProjectionList()
                     .Add (Property("Name"), "Name")
                     .Add (Property( ... )
                   );

crit.SetResultTransformer(Transformers.AliasToBean(typeof(PersonView));

return crit.List<PersonView>();

Mas, isso ainda significa que você terá que import a classe, para que NHibernate sabe sobre ele.

Usando a classe, NHibernate seria basicamente na dúvida sobre tudo que está envolvido, incluindo qual a tabela que você quis usar para Pessoa, e os mapeamentos de campo. NHibernate provavelmente poderia ser cortado para fazer ligação dinâmica com base na correspondência dos nomes ou algo assim, mas toda a idéia é criar os mapeamentos de simples objeto de dados antiga para os campos de banco de dados usando os arquivos XML.

Se não há uma boa razão para não mapear a classe, simplesmente adicionando o mapeamento vai lhe dar os melhores resultados ...

Dito isso, você não pode usar uma consulta nomeada para resultados diretamente injetar em uma classe não mapeado. Você precisaria dizer que as colunas de pôr em que campos ou em outras palavras, um mapeamento. ;). No entanto, você pode retornar valores escalares de uma consulta nomeada e você poderia tomar esses arranjos de objetos e construir sua coleção manualmente

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top