Cela dépend un peu de ce que vous voulez regrouper. Mais il existe une multitude de solutions.
Solution 1:
Disons que vous voulez groupe par notes, vous pouvez faire:
var query1 = from rating in db.Ratings
join comment in db.Comments
on rating.ID equals comment.RatingID
join user in db.Users
on comment.UserID equals user.ID
group new { comment, user } by rating into g
select new { g.Key, l = g.ToList() };
foreach (var row in query1)
{
// you get rows grouped by rating
Debug.WriteLine(row.Key.ID); // rating.ID
// and a list of comments/users per rating
foreach (var g in row.l)
{
Debug.WriteLine(g.comment.ID);
Debug.WriteLine(g.user.ID);
}
}
Cela vous donne une seule ligne par note. Et l'objet dynamique g
contient une liste de paires commentaire/utilisateur par évaluation.
Solution 2:
Cependant, comme @gertarnold mentionné, il est plus facile à lire juste l'objet que vous voulez regrouper par. Et puis traverser ses propriétés. Comme ceci:
var query2 = db.Ratings;
foreach (var rating in query2)
{
Debug.WriteLine(rating.name);
foreach (var comment in rating.Comments)
{
Debug.WriteLine(comment.name);
Debug.WriteLine(comment.User.name);
}
}
Ceci est beaucoup plus facile à comprendre. Il a un inconvénient de performance difficile, car il effectue une base de données distincte pour chaque commentaire dans la boucle interne. Si une note a beaucoup de nombreux commentaires, alors c'est très lent. Le premier exemple avec le regroupement tire tout dans une seule instruction de base de données SELECT
, ce qui est beaucoup plus rapide.
Solution 3:
Et il y a un moyen d'avoir le meilleur des deux solutions. Faites comme en solution 2 et ajouter un peu DataLoadOptions
devant lui:
DataLoadOptions options = new DataLoadOptions();
options.LoadWith<Rating>(rating => rating.Comments);
options.LoadWith<Comment>(comment => comment.User);
db.LoadOptions = options;
Cela précharger toutes les évaluations avec tous les objets enfants nécessaires dans un seul SELECT
. C'est rapide et facile à lire et à comprendre.
PS: Juste une note de côté: Les tableaux doivent être nommés au singulier. Dans ce cas, Rating
, Comment
et User
au lieu de Ratings
, Comments
et Users
. PS2: Pour obtenir également des notes sans commentaires dans la solution 1, vous devez convertir les jointures en jointures externes. Comme ceci:
var query1 = from rating in db.Ratings
join comment in db.Comments
on rating.ID equals comment.RatingID into j1
from comment in j1.DefaultIfEmpty()
join user in db.Users
on comment.UserID equals user.ID into j2
from user in j2.DefaultIfEmpty()
group new { comment, user } by rating into g
select new { g.Key, l = g.ToList() };
voir aussi: 101 LINQ Samples - Left outer join
ce groupe avez-vous besoin? – Backs
Si vous utilisez les propriétés de navigation, il se peut que vous n'ayez besoin d'aucun regroupement. –