简体   繁体   中英

Grouping list by property .NET Core 3.1 using Fluent API

I need to group data, based on a list property. the code below is a simulation of my current scenario:

using System;
using System.Collections.Generic;
using System.Linq;
using static teste.StudentClass;

namespace teste
{
    class Program
    {
        public static void Main(string[] args)
        {
            List<Student> students = new List<Student>
            {
            new Student {FirstName = "Terry", LastName = "Adams", ID = 120,
                Year = GradeLevel.SecondYear,
                ExamScores = new List<int>{ 99, 82, 81, 79}},
            new Student {FirstName = "Fadi", LastName = "Fakhouri", ID = 116,
                Year = GradeLevel.ThirdYear,
                ExamScores = new List<int>{ 99, 86, 90, 94}},
            new Student {FirstName = "Hanying", LastName = "Feng", ID = 117,
                Year = GradeLevel.FirstYear,
                ExamScores = new List<int>{ 93, 92, 80, 87}},
            new Student {FirstName = "Cesar", LastName = "Garcia", ID = 114,
                Year = GradeLevel.FourthYear,
                ExamScores = new List<int>{ 97, 89, 85, 82}},
            new Student {FirstName = "Debra", LastName = "Garcia", ID = 115,
                Year = GradeLevel.ThirdYear,
                ExamScores = new List<int>{ 35, 72, 91, 70}},
            new Student {FirstName = "Hugo", LastName = "Garcia", ID = 118,
                Year = GradeLevel.SecondYear,
                ExamScores = new List<int>{ 92, 90, 83, 78}},
            new Student {FirstName = "Sven", LastName = "Mortensen", ID = 113,
                Year = GradeLevel.FirstYear,
                ExamScores = new List<int>{ 88, 94, 65, 91}},
            new Student {FirstName = "Claire", LastName = "O'Donnell", ID = 112,
                Year = GradeLevel.FourthYear,
                ExamScores = new List<int>{ 75, 84, 91, 39}},
            new Student {FirstName = "Svetlana", LastName = "Omelchenko", ID = 111,
                Year = GradeLevel.SecondYear,
                ExamScores = new List<int>{ 97, 92, 81, 60}},
            new Student {FirstName = "Lance", LastName = "Tucker", ID = 119,
                Year = GradeLevel.ThirdYear,
                ExamScores = new List<int>{ 68, 79, 88, 92}},
            new Student {FirstName = "Michael", LastName = "Tucker", ID = 122,
                Year = GradeLevel.FirstYear,
                ExamScores = new List<int>{ 94, 92, 91, 91}},
            new Student {FirstName = "Eugene", LastName = "Zabokritski", ID = 121,
                Year = GradeLevel.FourthYear,
                ExamScores = new List<int>{ 96, 85, 91, 60}}
        };
                students.ToList().ForEach(x =>
                {
                    Console.WriteLine($"\t{x.FirstName}, {x.LastName}, {x.Year}");
                });
        }
    }
    public class StudentClass
    {

        public enum GradeLevel { FirstYear = 1, SecondYear, ThirdYear, FourthYear };
        public class Student
        {
            public string FirstName { get; set; }
            public string LastName { get; set; }
            public int ID { get; set; }
            public GradeLevel Year;
            public List<int> ExamScores;
        }


    }

}

currently, I have as a result the following:

Terry, Adams, SecondYear
Fadi, Fakhouri, ThirdYear
Hanying, Feng, FirstYear
Cesar, Garcia, FourthYear
Debra, Garcia, ThirdYear
Hugo, Garcia, SecondYear
Sven, Mortensen, FirstYear
Claire, O'Donnell, FourthYear
Svetlana, Omelchenko, SecondYear
Lance, Tucker, ThirdYear
Michael, Tucker, FirstYear
Eugene, Zabokritski, FourthYear

I have to change the return so that the data comes grouped by the LatsName property. expected output. How can I do this using Fluent Api? expected output (example):

{LastName:"Garcia": {FirstName:"Cesar", Year: "FourthYear"}, {FirstName:"Debra", Year: "ThirdYear"}, {FirstName:"Hugo", Year: "SecondYear"}},
{LastName:"Tucker": {FirstName:"Lance", Year: "ThirdYear"}, {FirstName:"Michael", Year: "FirstYear"}}
.... 

I'm trying a simple groupBy, but it returns an error message when converting:

students = students.GroupBy(x => x.LastName);

error message:

Cannot implicitly convert type 'System.Collections.Generic.IEnumerable<System.Linq.IGrouping<string, teste.StudentClass.Student>>' to 'System.Collections.Generic.List<teste.StudentClass.Student>'. An explicit conversion exists (are you missing a cast?)    

Your variable students is probably of the type List<Student> , so the conversion you are trying to do is not possible because the GroupBy returns IEnumerable<IGrouping<TKey, TSource>> .

This is the solution that maybe you are looking for

public class StudentDto 
{
   public string FirstName { get; set; }
   public GradeLevel Year { get; set; }
}

public class StudentGroup
{
   public string LastName { get; set; }
   public IEnumerable<StudentDto> Students { get; set; }
}

And now you can do the grouping on this way

IEnumerable<StudentGroup> groupedData = students.GroupBy(x => x.LastName)
   .Select(x => new StudentGroup { 
      LastName = x.Key,
      Students = x.Select(student => new StudentDto 
      {
         FirstName = student.FirstName,
         Year = student.Year
       }).ToList()
   });

On this way you will have all students grouped by their last name.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM