Linq 學習(1) Group & Join--網摘

Group
Group是進行分組操做,同SQL中的Group By相似。
原型以下:web

public   static  IEnumerable < IGrouping < TKey, TSource >>  GroupBy < TSource, TKey > ( 
    
this  IEnumerable < TSource >  source, 
    Func
< TSource, TKey >  keySelector)


它有幾個重載,返回類型有兩種:IEnumerable<IGrouping<TKey, TSource>> 和 IEnumerable<TResult>。
返回類型爲:IEnumerable<IGrouping<TKey, TSource>>
示例:
返回按學號分組學生的成績this

var  result  =   from  score  in  DataSource.Scores 
             
group  score  by  score.StudentID  into  scoreGroup 
             select scoreGroup;


scoreGroup爲IGrouping<TKey, TSource>類型,返回結果爲IEnumerable<IGrouping<TKey, TSource>>,既集合的集合,所以輸出時需用雙重循環。
IGrouping<TKey, TElement>接口定義爲:spa

public   interface  IGrouping < TKey, TElement >  : IEnumerable < TElement > , IEnumerable 
{ 
    TKey Key { 
get ; } 
}

其中Key爲分組依據的字段。orm

foreach  ( var   group   in  result) 
{ 
    
// 輸出分組依據的字段  
    Console.WriteLine( " \nStudent ID: "   +   group .Key); 

    
//  輸出組內成員  
     foreach  ( var  score  in   group ) 
    { 
        Console.WriteLine(score); 
    } 
} 

//  result: 
//  Student ID:1 
//  Student ID:1,Course ID:1,Score:78 
//  Student ID:1,Course ID:2,Score:60 
//  ... 

//  Student ID:2 
//  Student ID:2,Course ID:1,Score:59 
//  ...


等效的擴展方法調用實現爲:接口

var  result  =  DataSource.Scores.GroupBy(score  =>  score.StudentID);


返回類型爲:IEnumerable<TResult>
對分組結果進行一些包裝,如包裝爲匿名類型。
返回按學號分組學生的成績ci

var  result  =   from  score  in  DataSource.Scores 
             
group  score  by  score.StudentID  into  scoreGroup 
             select 
new  { StudentID  =  scoreGroup.Key, Group  =  scoreGroup };


匿名類型中Group爲IGrouping<TKey, TSource>類型。
等效的擴展方法調用實現爲:get

var  result  =  DataSource.Scores.GroupBy(score  =>  score.StudentID, 
    (key, 
group )  =>   new  { StudentID  =  key, Group  =   group  });


其餘一些重載使用方法相似。

Join

鏈接操做。原型

public   static  IEnumerable < TResult >  Join < TOuter, TInner, TKey, TResult > ( 
    
this  IEnumerable < TOuter >  outer, 
    IEnumerable
< TInner >  inner, 
    Func
< TOuter, TKey >  outerKeySelector, 
    Func
< TInner, TKey >  innerKeySelector, 
    Func
< TOuter, TInner, TResult >  resultSelector)


從Join方法原型能夠看出其使用方法。

內鏈接
選擇左右兩側集合都含有相對應的元素。
示例:
查詢學生的姓名、學科、成績。it

var  result  =   from  score  in  DataSource.Scores 
             
join  student  in  DataSource.Students  on  score.StudentID  equals  student.StudentID 
             
join  course  in  DataSource.Courses  on  score.CourseID  equals  course.CourseID 
             select 
new  { StudentName  =  student.Name, CourseName  =  course.CourseName, ScoreValue  =  score.Value }; 
//  result 
//  { StudentName = Andy, CourseName = C Language, ScoreValue = 78 } 
//  { StudentName = Andy, CourseName = Biophysics, ScoreValue = 60 } 
//  ... 
//  { StudentName = Bill, CourseName = C Language, ScoreValue = 59 } 
//  { StudentName = Cindy, CourseName = Biophysics, ScoreValue = 60 } 
//  ...


等效的擴展方法調用實現爲:io

var  result  =  
    DataSource.Scores.Join( 
    DataSource.Students, 
    score 
=>  score.StudentID, 
    student 
=>  student.StudentID, 
    (score, student) 
=>   new  { StudentName  =  student.StudentID, ScoreValue  =  score.Value, CourseID  =  score.CourseID }) 
    .Join(DataSource.Courses, 
    scostu 
=>  scostu.CourseID, 
    course 
=>  course.CourseID, 
    (scostu, course) 
=>   new  { StudentName  =  scostu.StudentName, CourseName  =  course.CourseName, ScoreValue  =  scostu.ScoreValue }); 


左外鏈接
當右側的鏈接的右側沒有左側對應的元素時,內鏈接會忽略左側元素。要想保留左側元素,能夠使用作外鏈接。右側被置爲默認值,如:引用類型被置爲空。
示例:

var  result  =  
    
from  student  in  DataSource.Students2 
    
join  score  in  DataSource.Scores  on  student.StudentID  equals  score.StudentID  into  Scores 
    
from  score  in  Scores.DefaultIfEmpty() 
    select 
new  { student  =  student, score  =  score  ==   default (Score)  ?   0  : score.Value }; 
//  result: 
//  { student = Student ID:5,Student Name:Erik, score = 78 } 
//  { student = Student ID:6,Student Name:Frank, score = 0 }  

等效的擴展方法調用實現爲: 
var  result  =  
    DataSource.Students2.GroupJoin( 
    DataSource.Scores, 
    student 
=>  student.StudentID, 
    score 
=>  score.StudentID, 
    (student, Scores) 
=>   new  { student  =  student, Scores  =  Scores }) 
    .SelectMany(
group   =>   group .Scores.DefaultIfEmpty(), 
    (
group , score)  =>   new  { student  =   group .student, score  =  (score  ==   null )  ?   0.0  : score.Value });


笛卡爾積
集合中的元素交錯鏈接。
示例:統計學生課程成績時的模板。

var  result  =   from  student  in  DataSource.Students 
             
from  course  in  DataSource.Courses 
             select 
new  { StudentName  =  student.Name, CourseName  =  course.CourseName, ScoreValue  =  ( double ? ) null  }; 
//  result: 
//  { StudentName = Andy, CourseName = C Language, ScoreValue =  } 
//  { StudentName = Andy, CourseName = Biophysics, ScoreValue =  } 
//  ... 
//  { StudentName = Bill, CourseName = C Language, ScoreValue =  } 
//  ... 
//  { StudentName = Cindy, CourseName = Fundamentals of Compiling, ScoreValue =  } 
//  ...  

等效的擴展方法調用實現爲: 
var  result  =  DataSource.Students.SelectMany( 
    student 
=>  DataSource.Courses 
        .Select( 
        course 
=>  
            
new  { StudentName  =  student.Name, CourseName  =  course.CourseName, ScoreValue  =  ( double ? ) null  }));


GroupJoin
鏈接分組。
方法原型爲: 

public   static  IEnumerable < TResult >  GroupJoin < TOuter, TInner, TKey, TResult > ( 
    
this  IEnumerable < TOuter >  outer, 
    IEnumerable
< TInner >  inner, 
    Func
< TOuter, TKey >  outerKeySelector, 
    Func
< TInner, TKey >  innerKeySelector, 
    Func
< TOuter, IEnumerable < TInner > , TResult >  resultSelector) 

//  result: 
//  Andy 
//  1----78 
//  2----60 
//  ... 
//  Bill 
//  1----59 
//  ... 
//  Cindy 
//  2----60 
//  ...


至關於組合了Group操做和Join操做。等效的操做以下:

var  result  =   from  item  in  
                 (
from  student  in  DataSource.Students 
                  
join  score  in  DataSource.Scores  on  student.StudentID  equals  score.StudentID 
                  select 
new  { StudentName  =  student.Name, CourseID  =  score.CourseID, Value  =  score.Value }) 
             
group  item  by  item.StudentName  into  Group 
             select 
new  { StudentName  =  Group.Key, Group  = Group };
相關文章
相關標籤/搜索