博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Linq 学习(1) Group & Join--网摘
阅读量:5291 次
发布时间:2019-06-14

本文共 5325 字,大约阅读时间需要 17 分钟。

Group
Group是进行分组操作,同SQL中的Group By类似。
原型如下:

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>>

示例:
返回按学号分组学生的成绩

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>接口定义为:

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

其中Key为分组依据的字段。

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>
对分组结果进行一些包装,如包装为匿名类型。
返回按学号分组学生的成绩

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>类型。
等效的扩展方法调用实现为:

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方法原型可以看出其使用方法。

内连接
选择左右两侧集合都含有相对应的元素。
示例:
查询学生的姓名、学科、成绩。

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 } 
//
 ...


等效的扩展方法调用实现为:

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 };

转载于:https://www.cnblogs.com/findchance/p/3159334.html

你可能感兴趣的文章
20141026--娱乐-箱子
查看>>
自定义分页
查看>>
Oracle事务
查看>>
任意输入10个int类型数据,把这10个数据首先按照排序输出,挑出这些数据里面的素数...
查看>>
String类中的equals方法总结(转载)
查看>>
图片问题
查看>>
bash使用规则
查看>>
AVL数
查看>>
第二章练习
查看>>
ajax2.0
查看>>
C#时间截
查看>>
C语言程序设计II—第九周教学
查看>>
C# 获取系统时间及时间格式转换
查看>>
WCF、WebAPI、WCFREST、WebService之间的区别
查看>>
2018-2019-2-20175332-实验四《Android程序设计》实验报告
查看>>
全栈12期的崛起之捡点儿有用的说说
查看>>
基础类型
查看>>
属性动画
查看>>
标识符
查看>>
Swift 常量&变量
查看>>