Mike Fielden
Mike Fielden

Reputation: 10153

Linq-to-sql query group by while still selecting details

Im going to try to describe this the best way I can. The best way I can think of it is to give you a dataset.

Animals
ID Type
1 Lions
2 Tigers
3 Bears

AnimalDetails
ID AnimalId Height Weight
1 1 62 inches 200lbs
2 1 56 inches 150lbs
3 1 23 inches 125lbs
4 2 47 inches 500lbs
5 2 88 inches 150lbs
6 2 15 inches 125lbs

If it helps, pretend like these tables are already joined

Maybe there is a FK to some other table that holds detailed data for each of these types of Animal; height, width, age, etc.

I want to group by Animal type (lion, etc) and select that but also select the details for the lion.

So I want the Key to be Lion then maybe a collection of lion information.

Does that make sense?

My attempt obviously wouldnt work but here it is anyway:

var animals = (from a in Animals   
               group a by new { AnimalType = a.Type }
               into grouped
               select grouped);

UPDATE Added a psuedo table structure. Im not looking for the 1 answer to this as this is obviously fake data, just looking for direction on how to achieve this.

Upvotes: 1

Views: 539

Answers (2)

Sinan AKYAZICI
Sinan AKYAZICI

Reputation: 3952

you lose id value in Animals using group by. if losing id value , you cannot use foreinKey between Animals and AnimalsDetail. So you not using group by With this code you can get the animalDetails.

    var listAnimals = new List<Animals>
                       {
                           new Animals {Id = 1, Name = "Lions"},
                           new Animals {Id = 2, Name = "Tigers"},
                           new Animals {Id = 3, Name = "Bears"}
                       };

    var listAnimalDetails = new List<AnimalDetails>
                                {
                                    new AnimalDetails {Id = 1, AnimalId = 1, Height = 62, Weight = 200},
                                    new AnimalDetails {Id = 2, AnimalId = 1, Height = 56, Weight = 150},
                                    new AnimalDetails {Id = 3, AnimalId = 1, Height = 23, Weight = 125},
                                    new AnimalDetails {Id = 4, AnimalId = 2, Height = 47, Weight = 500},
                                    new AnimalDetails {Id = 5, AnimalId = 2, Height = 88, Weight = 150},
                                    new AnimalDetails {Id = 6, AnimalId = 2, Height = 15, Weight = 125}
                                };


    var join = (from anm in listAnimals
                   join anmD in listAnimalDetails
                   on anm.Id equals anmD.AnimalId
                   select new
                   {
                       Animal = anm.Name,
                       H = anmD.Height,
                       W = anmD.Weight
                   }).ToList();

after this you can using group by on the join. I hope you will help.

Upvotes: 0

ryan1234
ryan1234

Reputation: 7275

I would read this SO article: Linq with Left Join on SubQuery containing Count

Do your normal group by on Animals and then join on the AnimalId to the details table to get the detail attributes just once.

EDIT:

        var query = (from d in details
                     join a in
                        (from animal in animals
                         group animal by animal.Name into g
                         select new { Name = g.Key }) on d.Name equals a.Name
                     select new { a.Name, d.Height, d.Weight }).ToList();

The query above assumes the pseudo data tables you have are not joined. If they are already joined, then I don't understand why you would want to group by animal name and then pickup details since the details in your example occur more than once per animal. (1 lion has multiple details records).

Upvotes: 2

Related Questions