2010-09-20 5 views
2

J'ai 2 entités Rôle & Traduction.
rôle -> ROLE_ID, Code
Traduction -> Code, Langue, NomNHibernate Left Outer Rejoindre des entités non liées

L'idée est de dire pour un certain rôle, qu'il a le nom anglais, nom français et ainsi de suite. Par exemple:
Un rôle (1, 'Rol_001') peut avoir les relations: Traduction ('Rol_001', 'English', '') & Traduction ('Rol_001', 'Français', '').

Je voudrais exprimer la requête SQL suivante dans HQL:


select r.Role_ID, t.Name 
from Role r left outer join Translation t 
    on r.Code = t.Code and t.Language = @lang; 

Dans mes fichiers de mappage Je n'ai aucune relation entre les 2 entités, mais la requête HQL suivante fonctionne comme si elle est jointure Si je change la HQL en jointure externe gauche, j'obtiens le chemin attendu pour l'exception de jointure.

Pouvez-vous m'aider avec ce qui suit:
1- Dois-je changer mes fichiers de cartographie?
2- Si je peux conserver les fichiers de mapping tels quels, comment écrire une telle requête dans HQL?
3- Comment fonctionne vraiment HQL? Pourquoi une telle requête de jointure externe ne fonctionne-t-elle pas? Je dois manquer quelque chose ici!

Edit:
Maintenant, je suis en utilisant le code suivant en fonction de la suggetion utiliser CreateSQL:


ISQLQuery query = session.CreateSQLQuery("select m.MedicineTypeID, t.Name, m.IsDeleted from MedicineType m left outer join Translation t on m.Code = t.Code and t.Language = :language"); 
query.SetString("language", language); 
IList rawLookup = query.List(); 

IList medicineTypesLookup = new List(rawLookup.Count); 
foreach (object[] lookup in rawLookup) 
{ 
    medicineTypesLookup.Add(new Lookup((int)lookup[0], (string)lookup[1], (bool)lookup[2])); 
} 
return medicineTypesLookup; 

Cela fonctionne mais je veux utiliser Query.list() pour obtenir le résultat directement au lieu de le convertir moi-même. J'ai essayé d'utiliser query.AddEntity(typeof(Lookup)); mais j'ai l'exception NHibernate.MappingException: No persister for: DAL.Domain.Lookup
La recherche est juste un POCO et ne correspond à aucune table de base de données. Son fichier de mappage est tout simplement <import class="Lookup" />

+2

HQL utilise des relations cartographié, pas arbitraire clauses de jointure. Vous pouvez utiliser SQL pour y parvenir. –

+0

Ceci est un SQL Server CE, puis-je exécuter une instruction SQL en utilisant directement NHibernate ou dois-je utiliser SqlCeConnection et SqlCeCommand pour ExecuteReader l'instruction SQL et obtenir le résultat? –

+0

Je vois que je peux utiliser session.CreateSQLQuery mais le résultat est un Object []. J'essaie de trouver un moyen d'obtenir le résultat comme IList . –

Répondre

2

J'ai finalement trouvé la réponse:

ISession session = NHibernateHelper.Session; 
ISQLQuery query = session.CreateSQLQuery("select m.MedicineTypeID as ID, t.Name, m.IsDeleted from MedicineType m left outer join Translation t on m.Code = t.Code and t.Language = :language"); 
query.setString("language", language); 
IList lookup = query.SetResultTransformer(Transformers.AliasToBean()).List(); 
return lookup; 
Et la recherche est une classe POCO avec un constructeur parameterless et 3 propriétés ID , Nom et IsDeleted.

Je tiens à remercier Kelly et Diego Mijelshon pour leurs conseils. Bien qu'ils ne fournissent pas la réponse complète, l'utilisation de Session.CreateSqlQuery() était un indice très utile.

donc la solution complète est session.createSQLQuery et query.SetResultTransformer

Note: Transformers.AliasToBean() est si java.

Edit: http://docs.jboss.org/hibernate/orm/3.2/api/org/hibernate/impl/SQLQueryImpl.html pour la méthode correcte de setString()

1

Vous devez définir la relation dans les applications ou faire une sous-requête

+0

Pouvez-vous me montrer un exemple de sous-requête? –

+1

en regardant à nouveau votre exemple, vous devrez probablement utiliser 2 requêtes séparées (une pour les rôles et une pour la langue), puis une linq left join externe. Mais, ce n'est pas une bonne solution IMO, vous devriez vraiment juste définir la relation simple dans les mappages ou utiliser session.CreateSqlQuery(). – Kelly