Question

J'utilise une requête nommée personnalisée avec NHibernate à laquelle je souhaite renvoyer une collection d'objets Person. L'objet Person n'est pas mappé avec un mappage NHibernate, ce qui signifie que je reçois l'exception suivante:

  

System.Collections.Generic.KeyNotFoundException:   La clé donnée n'était pas présente dans le   dictionnaire.

Il est lancé lorsque la session est créée car il ne trouve pas le nom de la classe lorsqu'il appelle NHibernate.Cfg.Mappings.GetClass (String className). Tout cela est assez compréhensible, mais je me demandais s’il existait un moyen de dire à NHibernate d’utiliser la classe même si je n’ai pas de mappage pour le faire.

Était-ce utile?

La solution 5

Pour résoudre ce problème, j’ai fini par utiliser TupleToPropertyResultTransformer et à fournir la liste des valeurs de propriété. Il existe quelques limitations à cela, la principale étant que la requête SQL doit renvoyer les résultats dans le même ordre que celui dans lequel vous fournissez vos propriétés au constructeur TupleToPropertyResultTransformer.

Les types de propriétés étant également déduits, vous devez être prudent avec les colonnes décimales ne renvoyant que des valeurs entières, etc. objets dans NHibernate.

Autres conseils

Pourquoi n'utilisez-vous pas:

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

Il insérera les données de chaque colonne de votre requête dans les propriétés de l'objet Personne en utilisant un alias de colonne comme nom de propriété.

Comment créer une requête renvoyant des instances d’un type non mappé?

Je pense que Michal a raison, et vous devriez peut-être regarder les projections. (C'est du moins ce que je pense que vous recherchez.)

Vous créez une requête sur un type mappé, puis vous pouvez "projeter" cette requête sur un "DTO". Pour ce faire, vous devez "importer" votre classe Person afin qu'elle soit connue de NHibernate et vous devez utiliser un ResultTransformer.

Quelque chose comme ça:

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

Mais cela signifie toujours que vous devrez importer la classe, afin que NHibernate le sache.

En utilisant la classe, NHibernate devinerait essentiellement tout ce qui est impliqué, y compris la table que vous voulez utiliser pour Person et les correspondances de champs. NHibernate pourrait probablement être obligé de faire une liaison dynamique basée sur la correspondance des noms ou quelque chose du genre, mais l’idée est de créer les mappages à partir d’un ancien objet de données sur les champs de la base de données à l’aide des fichiers xml.

S'il n'y a pas vraiment de bonne raison de ne pas mapper la classe, le simple fait d'ajouter la mappage vous donnera les meilleurs résultats ...

Cela dit, vous ne pouvez pas utiliser une requête nommée pour injecter directement les résultats dans une classe non mappée. Vous devrez lui indiquer quelles colonnes mettre dans quels champs ou, en d'autres termes, un mappage. ;) Cependant, vous pouvez renvoyer des valeurs scalaires à partir d’une requête nommée. Vous pouvez également récupérer ces tableaux d’objets et construire votre collection manuellement.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top