|
@@ -0,0 +1,131 @@
|
|
1
|
+> Linq概述
|
|
2
|
+- Linq(语言集成查询)在C#中集成了查询语法,可以用相同的语法访问不同的数据源。Linq提供了不同数据源的抽象层,所以可以使用相同的语法。
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+> 标准的查询操作符
|
|
6
|
+- Where OffType<TResult>
|
|
7
|
+ - 筛选操作符定义了返回元素的条件。在Where查询操作符中可以使用谓词。例如,lambda表达式定义的谓词,来返回布尔值。OfType<TResult>根据类型筛选元素,只返回TResult类型的元素
|
|
8
|
+- Select SelectMany
|
|
9
|
+ - 投射操作符用于把对象转换为另一个类型的新对象。Select和SelectMany定义了根据选择器函数选择结果值得投射
|
|
10
|
+- OrderBy\ThenBy\OrderByDescending\ThenByDescending\ThenByDescending\Reverse
|
|
11
|
+ - 排序操作符改变所返回的元素的顺序。OrderBy按升序排序,OrderByDescending按降序排序。如果第一次排序的结果很类似,就可以使用ThenBy和ThenBy Deacending 操作符进行第二次排序。Reverse反转集合中元素的顺序
|
|
12
|
+
|
|
13
|
+- Join\GroupJoin
|
|
14
|
+ -连接操作符用于合并并不直接相关的集合。使用Join操作符,可以根据键选择器函数连接两个集合,这个类似于SQL中的JOIN。GroupJoin操作符连接两个集合,组合其结果
|
|
15
|
+
|
|
16
|
+- GroupBy\ToLookup
|
|
17
|
+ - 组合操作符把数据放在组中。GroupBy操作符组合有公共键的元素。ToLookup通过创建一个一对多字典,来组合元素
|
|
18
|
+
|
|
19
|
+- Any\All\Contains
|
|
20
|
+ - 如果元素序列满足指定的条件,限定符操作符就返回布尔值。Any确定集合中是否有满足为此函数的元素;All确定集合中的所有元素是否都满足谓词函数;Contains检查某个元素是否在集合中
|
|
21
|
+
|
|
22
|
+- Take\Skip\TakeWhile\SkipWhile
|
|
23
|
+ - 分区操作符返回集合的一个子集。Take、Skip、TakeWhile和SkipWhile都是分区操作符。使用它们可以得到部分结果。使用Take必须指定要从集合中提取的元素个数;Skip跳过指定的元素个数,提取其他元素;TakeWhile提取条件为真的元素,SkipWhile跳过条件为真的元素。
|
|
24
|
+
|
|
25
|
+- Distinct\Union\Intersect\Except\Zip
|
|
26
|
+ - Set操作符返回一个集合。Distinct从集合中删除重复的元素,除了Distinct之外,其他Set操作符都需要两个集合。Union返回出现在其中一个集合中的唯一元素。Intersect返回两个集合中都有的元素。Except返回只出现在一个集合中的元素。Zip把两个集合合并为一个。
|
|
27
|
+
|
|
28
|
+- First\FirstOrDefault\Last\LastOrDefault\ElementAt\ElementAtOrDefault\Single\SingleOrDefault
|
|
29
|
+ - 这些元素操作符仅返回一个元素。First返回第一个满足条件的元素。FirstOrDefault类似于First,但如果没有找到满足条件的元素,就返回类型的默认值。Last返回最后一个满足条件的元素。ElemAt指定了要返回的元素的位置。Single只返回一个满足条件的元素。如果有多个元素都满足条件,就抛出一个异常。所有的XXOrDefault方法都类似与以相同前缀开头的方法,但如果没有找到该元素,他们就返回类型的默认值
|
|
30
|
+
|
|
31
|
+- Count\Sum\Min\Max\Average\Aggregate
|
|
32
|
+ - 聚合操作符计算集合的一个值。利用这些聚合操作福,可以计算所有值得总和、所有元素的个数、值最大和最小的元素,以及平均值等
|
|
33
|
+
|
|
34
|
+- ToArray\AsEnumerable\ToList\ToDictionary\Cast<TResult>
|
|
35
|
+ - 这些转换操作符将集合转换为数组:IEnumerable、IList、IDictionary等。Cast方法把集合的每个元素类型转换为泛型参数类型
|
|
36
|
+
|
|
37
|
+- Empty\Range\Repeat
|
|
38
|
+ - 这些生成操作符返回一个心机和。使用Empty时集合时空的:Range返回一系列数字:Repeat返回一个始终重复一个值得集合
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+**筛选**
|
|
42
|
+- 使用where子句,可以合并多个表达式。例如,找出赢得至少15场比赛的巴西和奥地利赛车手。
|
|
43
|
+```
|
|
44
|
+var racers = from r in Formulal.GetChampions()where r.Wins> 15 &&(r.Country=="Brazil" || r.Country="Austria") select r;
|
|
45
|
+
|
|
46
|
+foreach(var r in rqacers)
|
|
47
|
+{
|
|
48
|
+ WriteLine($"{r:A}");
|
|
49
|
+}
|
|
50
|
+
|
|
51
|
+var racers=Formulal.GetChampions().Where(r=>r.Wins>15 &&(r.Country=="Brazil" || r.Country== "Austria")).Select(r=>r);
|
|
52
|
+```
|
|
53
|
+> 用索引筛选
|
|
54
|
+- 不能使用Linq查询的一个例子是Where()方法的重载。在Where()方法的重载中,可以传递第二个参数--索引。索引是筛选器返回的每个结果的计数器。可以在表达式中使用这个索引,执行基于索引的计算。
|
|
55
|
+```
|
|
56
|
+var racers =Formulal.GetChamplons().Where((r,index)=>r.LastName.StartsWith("A") && index%2!=0);
|
|
57
|
+foreach (var r in racers)
|
|
58
|
+{
|
|
59
|
+ WriteLine(${r:A});
|
|
60
|
+}
|
|
61
|
+```
|
|
62
|
+
|
|
63
|
+> 类型筛选
|
|
64
|
+
|
|
65
|
+-为了基于类型的筛选,可以使用OfType()扩展方法。这里数组数据包含string和int对象。使用OfType()扩展方法,把string类传送给泛型参数,就从集合中仅返回字符串
|
|
66
|
+```
|
|
67
|
+object[] data={"one",2,3,"four","five",6};
|
|
68
|
+var query=data.OfType<string>();
|
|
69
|
+foreach(var s in query)
|
|
70
|
+{
|
|
71
|
+ WriteLine(s);
|
|
72
|
+}
|
|
73
|
+```
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+> LINQ查询中的变量
|
|
77
|
+
|
|
78
|
+- 在为分组编写的LINQ查询中,Count方法调用了多次。使用了let子句可以改变这种方式。let允许在LINQ查询中定义变量:
|
|
79
|
+```
|
|
80
|
+var countries=Formulal.GetChampions().GroupBy(r=>r.Country).Select(g=>new{Group=g,Count=g.Count()}).OrderByDescending(g=>g.Count).ThenBy(g=>g.Group.Key).Where(g=>g.Count>=2).Select(g=>new
|
|
81
|
+{
|
|
82
|
+ Country=g.Group.Key,
|
|
83
|
+ Count=g.Count
|
|
84
|
+});
|
|
85
|
+```
|
|
86
|
+
|
|
87
|
+> 内连接
|
|
88
|
+- 使用join子句可以根据特定的条件合并两个数据源,但之前要获得两个要连接的列表。
|
|
89
|
+- 例子:在一级方程式比赛中,有赛车手冠军和车队冠军。赛车手从GetChampions()方法中返回,车队从GetConstructorChampions()方法中返回。现在要获得一个年份表,列出每年的赛车手冠军和车队冠军
|
|
90
|
+ - 先定义两个查询,用于查询赛车手和车队
|
|
91
|
+ ```
|
|
92
|
+ var racers=from r in Formulal.GetChampions() from y in r.Years select new
|
|
93
|
+ {
|
|
94
|
+ Year=y,
|
|
95
|
+ Name=r.FirstName+""+r.LastName
|
|
96
|
+ };
|
|
97
|
+ var teams=from t in Formulal.GetContructorChampions() from y in t.Years select new
|
|
98
|
+ {
|
|
99
|
+ Year =y,
|
|
100
|
+ Name=t.Name
|
|
101
|
+ };
|
|
102
|
+ ```
|
|
103
|
+ - 有了这两个查询,再通过join子句,根据赛车手获得冠军的年份和车队获得冠军的年年份进行连接。select子句定义了一个新的匿名类型,它包含Year、Racer和Team属性。
|
|
104
|
+ ```
|
|
105
|
+ var racersAndTeams=(from r in racers join t in teams on r.Year equals t.Year select new
|
|
106
|
+ {
|
|
107
|
+ r.Year,
|
|
108
|
+ Champion=r.Name,
|
|
109
|
+ Constructor=t.Name
|
|
110
|
+ }).Take(10);
|
|
111
|
+ WriteLine("Year World Champion\t Constructor Title");
|
|
112
|
+ foreach (var item in racersAndTeams)
|
|
113
|
+ {
|
|
114
|
+ WriteLine($"{item.Year}:{item.Champion,-20}{item.Constructor}");
|
|
115
|
+ }
|
|
116
|
+ 也可以把它们合并为一个LINQ查询
|
|
117
|
+ var racersAndTeams=
|
|
118
|
+ {
|
|
119
|
+ from r in
|
|
120
|
+ from r1 in Formulal.GetChampions()
|
|
121
|
+ from yr in r1.Years
|
|
122
|
+ select new
|
|
123
|
+ {
|
|
124
|
+ Year=yr,
|
|
125
|
+ Name=r1.FirstName + "" +r1.LastName
|
|
126
|
+ }
|
|
127
|
+ join t in
|
|
128
|
+ from t1 in Formulal.GetContructorChampios
|
|
129
|
+
|
|
130
|
+ }
|
|
131
|
+ ```
|