[LINQ]SelectMany 用法

SelectMany

SelectMany用法

SelectMany 算是 Select 的好兄弟,只是SelectMany用起來不像Select那麼的直覺。 SelectMany的結果就有點像把資料攤平的感覺,或者可以把它想像成SQL的CROSS JOIN。

舉例來說:

 以兩個有關聯性的物件來講,一個Student可以選多種Course,如以下範例:

public class Student
{
    public int Id { get; set; }
    public string Name { get; set; }
    public List<Course> Course { get; set; }
}

public class Course
{
    public int StudentId { get; set; }        
    public string CourseName { get; set; }
}

假設我們現在有兩筆Student資料的List,且每一筆的Student都有一個或多個Course

List<Student> t = new List<Student>()
{
    new Student()
    {
        Id = 1,
        Name = "Miles",
        Course = new List<Course>() 
        { 
            new Course(){
            StudentId = 1,
            CourseName = "數學"
            },
            new Course(){
            StudentId = 1,
            CourseName = "國文"
            },
        }
    },
    new Student()
    {
        Id = 2,
        Name = "Bob",
        Course = new List<Course>()
        {
            new Course(){
                StudentId = 2,
                CourseName = "數學"
            }
        }
    }
};

所以當我們要輸出該學生有那些課程的時候,會用以下方式

foreach (var item in t)
{
    Console.WriteLine(item.Id + "  " + item.Name);
    foreach (var c in item.Course)
    {
        Console.WriteLine(c.CourseName);
    }
}

輸出結果:

出動SelectMany

而SelectMany的用意呢,則可以少掉item.Course那層迴圈,讓每一個Course都對到一筆Student,如以下範例:

var data = t.SelectMany(
        // 第一個參數,代表每一筆Student各包含哪些Course
        std => std.Course, 
        // 第二個參數,則是產生新的匿名型別
        (std, crs) => new { std.Id, std.Name, crs.CourseName }
        );

foreach (var item in data)
{
    Console.WriteLine(item.Id);
    Console.WriteLine(item.Name);
    Console.WriteLine(item.CourseName);
}

輸出結果:

這情形對我來說就像是把資料攤平的感覺,資料的輸出讓每一筆Course都對到一筆Student,而不是每一個Student對到多個Course。

雖然知道SelectMany的用法,只是一開始我也都不知道SelectMany到底能用在什麼地方,導致一直忘記。    而剛好今天在研究用Entity Framework達到LeftJoin的語法,原來SelectMany用在這個地方,整個超級適合阿!!!    請點 Join 與 GroupJoin用法

 

 

一天一分享,身體好健康。

該追究的不是過去的原因,而是現在的目的。