2009-12-07 7 views
0

MISE À JOUR: J'ai répondu à ma question ci-dessous, jetez un coup d'oeil et laissez-moi savoir si vous avez une meilleure façon de le faireNHibernate résultats sql-requêtes différentes de requête directe résultats


exécutif résumé:
lorsque j'appelle ma fonction sqlserver à partir de SQL Management Studio, j'obtiens une liste avec les résultats {1, 2, 3}. lorsque j'appelle la méthode à partir d'un code utilisant NHibernate, j'obtiens cette liste {1, 1, 1}. ('1' est une ligne de résultat entière, pas le scalaire '1') J'ai aussi essayé avec différents ensembles de données et j'ai eu le même comportement.

la longue histoire:
J'ai une fonction SQL dans le serveur SQL, appelé getHistory (itemId). il retourne une table avec les résultats. lorsque j'interroge à partir de SQL Management Studio, j'obtiens une liste de résultats. Je requête en appelant la fonction comme ceci:

select * from GetHistory(10001)

sur mon DB donné ce résultat en 3 lignes. chaque rangée a un temps, un type et une description.
Dans NHibernate, j'ai créé une nouvelle entité spécialement pour cela, car il n'y a pas de table/entité organique. j'ai donc une cartographie:

<?xml version="1.0" encoding="utf-8" ?> 
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" 
namespace="myNamespace" assembly="myAssembly"> 
<class name="HistoryEvent"> 
<id name="id" type="long" access="field"> 
    <column name="Id"/> 
    <generator class="native"/> 
</id> 
<property name="type" column="Type" type="short" access="field"/> 
<property name="time" column="Time" type="datetime" access="field"/> 
<property name="description" column="Description" type="string" access="field"/> 
</class> 

<sql-query name='GetHistory'> 
    <return class='HistoryEvent, myAssembly' alias='historyEvent'/> 
<![CDATA[SELECT * FROM GetHistory(:id)]]> 
</sql-query> 
</hibernate-mapping> 

l'objet métier ressemble à ceci:

public class HistoryEvent 
{ 
    private long id; 
    private short type; 
    private string description; 
    private DateTime time; 
     ... here be properties with public getter etc... 
    } 

et enfin, j'appelle cette fonction de mon code comme ceci:

IList result = s.GetNamedQuery("GetHistory").SetInt64("id", id).List(); 

lors de l'inspection cette liste avec le débogueur je reçois 3 entités qui sont la même rangée 3 fois. J'ai également essayé d'utiliser la requête directement depuis NHibernate (en utilisant sql-query) au lieu de passer par la fonction DB, mais j'ai obtenu les mêmes résultats.
mon intuition est que quelque chose ne va pas avec ma cartographie, ou quelque chose ne va pas avec NHibernate :)
AIDE!

Répondre

0

ok, peu de temps après avoir posté la question, je l'ai compris.
écrire tout cela m'a vraiment aidé je suppose. c'était le problème:
la colonne Id que j'ai utilisée n'était pas unique. c'est un identifiant, mais pas l'identifiant de la requête. pourquoi donc? parce que ma requête renvoie une union de trois requêtes de trois tables différentes, et l'ID retourné était en fait l'ItemId (même celui qui a été passé à la fonction!)

alors maintenant je devais avoir un ID unique. J'ai tenté d'utiliser brièvement la balise composite-id de NHibernate au lieu de l'id - mais face à la difficulté, j'ai décidé de ne pas perdre plus de temps sur les trucs automagical et de renvoyer les ID de la requête. Découvrant que je ne pouvais pas utiliser SELECT IDENTITY() INTO ... dans des fonctions internes avec une variable de table, j'ai considéré RAND pendant une seconde et j'ai finalement utilisé ROW_NUMBER() OVER (SORT BY blah) pour générer mes faux IDs . pour l'instant cela fonctionne plutôt bien, même si ce code ne gagnerait pas un concours de beauté.
PS: Avez-vous reçu des suggestions pour une meilleure façon de générer un ID? ou avez-vous déjà eu l'identité composite pour travailler pour vous? laissez-moi savoir ...

+0

une meilleure façon de générer des ID serait la fonction NEWID() dans le serveur SQL. il génère un nouveau GUID qui pourrait être utilisé pour ce scénario. –

Questions connexes