2

I want to know if it's possible to get a List<IGrouping<string, IGrouping<string, T>>> out of a Linq expression. What I want to do is order songs by genre and artist, but in a format where I can iterate through each genre and for every genre, iterate for each album. If it's possible how can it be done? Or is there a better approach to what I want to achieve?

Here's my Song class

public class Song
{
    [StringLength(100)]
    public string Album { get; set; }

    public int Id { get; set; }

    [StringLength(100)]
    public string Title { get; set; }

    [StringLength(100)]
    public string Genre { get; set; }

    [StringLength(255)]
    public string Comment { get; set; }

    [StringLength(4)]
    public string Year { get; set; }

    [StringLength(100)]
    public string Author { get; set; }

    public int Length { get; set; }

    [StringLength(255)]
    public string Photo { get; set; }

    [StringLength(255)]
    public string FileName { get; set; }

    public string Extension { get; set; }
}

And this query I had here

var songs = db.Songs.GroupBy(s => s.Genre).ToList();

gives me a List<IGrouping<string, Song>> but what I want is to further group by Artist.

Jairo
  • 306
  • 3
  • 12
  • Possible duplicate of [Linq Getting Customers group by date and then by their type](http://stackoverflow.com/questions/19703034/linq-getting-customers-group-by-date-and-then-by-their-type) – Clint Jan 12 '16 at 16:26

3 Answers3

5

What I wanted was a List<IGrouping<string, IGrouping<string, Song>>> and this code gives me exactly what I want

            var queryNestedGroups =
            (from song in db.Songs
            group song by song.Genre into newGroup1
            from newGroup2 in
                (from song in newGroup1
                 group song by song.Author)
            group newGroup2 by newGroup1.Key).ToList();

(though I'm not quite sure how to translate it into linq method syntax).

Thanks to everyone who commented and/or answered.

Jairo
  • 306
  • 3
  • 12
  • Actually this is quite interesting, I've never seen such an usage. +1 – Ivan Stoev Jan 12 '16 at 18:13
  • @IvanStoev - Yeah it is :) This is [nested grouping](https://msdn.microsoft.com/en-us/library/bb545974.aspx). – Rahul Singh Jan 13 '16 at 06:20
  • @RahulSingh Lol, you've got me! Somehow missed that info, thanks for the link. Not quite intuitive though, especially group **newGroup2** by **newGroup1.Key**, wondering how it will look at the third level, and also in method syntax. Anyway. – Ivan Stoev Jan 13 '16 at 07:26
2
var songs = db.Songs.GroupBy(s => s.Genre, (genre, genreGroup) => new 
                                    { 
                                       Genre = genre, 
                                       ArtistGroup = genreGroup.GroupBy(s => s.Artist)
                                    });

This will return almost what you want, however IGrouping<string, IGrouping<string, Song>> can only be returned if you implement IGrouping<K,V> with your own class and new that up instead of the anonymous type I used above.

Rahul Singh
  • 21,585
  • 6
  • 41
  • 56
jamespconnor
  • 1,382
  • 14
  • 29
0

Try adding a second grouping to the results of the first

var songs = db.Songs.GroupBy(s => s.Artist).SelectMany(s => s.GroupBy (d =>  d.Genre)).OrderBy (s => s.Key).ToList();
user5606561
  • 141
  • 2