2010-07-16 5 views
1
public class Case 
{ 
    public int Id { get; set; } 
    public string Number { get; set; } 
    public Employee Employee { get; set; } 
} 

public class Employee 
{ 
    public int Id { get; set; } 
    public string EmployerIdentifier { get; set; } 
    public Case Case { get; set; } 
} 

Il existe une relation un à un entre Case et Employee. Cependant, il existe plusieurs enregistrements dans la base de données représentant le même employé. Pour trouver ces enregistrements, nous regardons le EmployerIdentifier. Donc, si je n'ai que le Employee.Id, comment puis-je écrire une requête NHibernate qui retourne tous les cas pour cet employé. En SQL je le ferais en rejoignant deux fois la table employee (voir l'exemple ci-dessous).NHibernate comment joindre à la table deux fois dans HQL

Declare @TargetEmployeeID bigint 
set @TargetEmployeeID = 246834 
select * from Cases C 
inner join Employees E on E.EmployeeID = C.EmployeeID 
inner join Employees EST on EST.EmployerIdentifier = E.EmployerIdentifier 
where EST.EmployeeID = @TargetEmployeeID 

Comment le ferais-je en utilisant HQL?

Répondre

0

C'est en fait très simple dans HQL. Essayez ceci:

SELECT Case c INNER JOIN FETCH c.Employee WHERE c.Employee.EmployerIdentifier=:employerId

Si je me souviens bien, cependant, ce contournera le chargement paresseux si c'est quelque chose que vous êtes préoccupé par.

+0

Cela ne correspond pas à ce que je cherchais. Note dans le sql ci-dessus, je dois rejoindre deux fois à la table des employés. Pour le faire comme vous le suggérez, je devrais avoir le EmployeeIdentifier mais je ne l'ai pas initialement. Je pourrais faire un aller-retour à la DB pour l'obtenir mais j'essayais d'éviter cela. – Kevin

1

Vous pouvez utiliser la logique suivante.

Utilisez une requête en mémoire - IQueryable.

Votre première requête consistera à identifier la liste des employés communs aux entités Employee et EmployeeIdentifier. Ce sera une requête en mémoire.

var caseList = new IList<Case>(); 

IQueryable<EmployeeIdentifier> empIdenList = Persister.Session.Query<EmployeeIdentifier>().Where(ei => ei.EmployeeId = 246834); 

caseList = Persister.Session.Query<Case>().Where(e => empIdenList.Contains(e.Employee)).ToList<Case>(); 

Remarque - Nous l'appel ToList() seulement dans la 2ème requête et c'est lorsque la requête se fait générée. Vous pouvez utiliser NHIbernate Profiler pour voir le SQL réel qui est généré.

Référez-vous à NHibernate.Linq DLL pour en savoir plus sur Query().

Questions connexes