2010-08-16 5 views
1

Je dois écrire la méthode en C# qui retournera un dictionnaire spécifique de DB. Disons que les données stockées dans 2 tables ressemble à:expression lambda - équivalent de sql outer join

Groupes de table (id, nom):

1, 'Management' 
2, 'IT Department' 
3, 'Production' 

Les utilisateurs (id, nom, groupeId, ProjectID):

1, 'John', 1, 1 
2, 'Ben', 2, 1 

maintenant Je dois vérifier que dans chaque projet, chaque groupe n'a pas moins d'un utilisateur. La requête SQL pour obtenir ces informations seront:

declare @projectId int; 
set @projectId = 1; 

select g.Name, case when(isnull(u.id,0) > 0) then 1 else 0 end HasUsers 
from groups g 
left join users u 
on g.id = u.groupId and u.projectId = @projectId; 

Les informations qui sont retournés de cette requête ressemble ci-dessous:

'Management', 1 
'IT Department', 1 
'Production', 0 

Ce qui est si spécial dans la requête? La condition de projectId est incluse dans la partie 'join', pas dans la partie 'where'. En conséquence, la ligne pour le groupe 'Production' est retournée avec la valeur 0. Lorsque nous passons la condition pour projectId à 'où part' l'enregistrement ne sera pas présent dans le résultat de retour. Enfin la question - est-il possible d'obtenir un effet similaire en utilisant une expression lambda? (Je sais que je peux obtenir 2 collections et en utilisant une sorte de déclaration de boucle obtenir le résultat final, mais ce n'est pas un sujet de cette question)

salutations
yaki

Répondre

0

LINQ jointure externe requêtes prennent la forme de ceci:

from x in collection 
join y in otherCollection on x.Key equals y.Key into g 
from o in g.DefaultIfEmpty() 
select new Whatever { 
    Something = x, 
    Other = o 
}; 

S'il n'y a pas y lié à se joindre à la x, le o choisi de g sera nulle

+0

Thanx pour la réponse. Oui, je connais la syntaxe linq pour la jointure externe mais elle n'atteint pas le paramètre pour projectId (qui était très important dans ce cas). –

0

semi tir dans l'obscurité:

from g in groups 
join u in users on 
new { a = g.id, b=u.projectid } equals new { a = u.groupid, b = [var_goes_here] } into t 
from u in ps.DefaultIfEmpty() 
select new { GroupName = g.name, HasUsers = u == null ? 0 : 1 }; 
3

Ok, je pense que j'ai tout compris par moi-même. Le sql produit est un peu plus compliqué que prévu dans la publication originale, mais le résultat est le même.

var query = db 
    .Groups 
    .GroupJoin(db.Users.Where(u => u.projectId == 1) , g => g.Id, u => u.groupId, (g, u) => new { u, g }) 
    .SelectMany(x => x.u.DefaultIfEmpty(), (g,u) => new {Group = g.g, Users = u}) 
    .Select(res => new {Group = res.Group.Name, Counter = (res.Users != null)});