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