本文介绍Linq的使用方法

  1. linq介绍

    1. LINQ只不过是实现IEnumerableIQueryable接口的类的扩展方法的集合。
    2. LINQ可以查询IEnumerable集合或者IQueryable数据源
    3. 查询语法
    4. List<string> list = new List<string>() { "a", "b", "cb", "d", "e" };
    5. var result = from s in list where s.Contains("b") select s;
    6. 方法语法
    7. 方法语法的使用就是调用Enumberable或者Queryable的扩展方法
    8. List<string> list = new List<string>() { "a", "b", "cb", "dc", "e" };
    9. var result = list.Where(s => s.Contains("c"));
    10. 上面Where中传递的是一个lambda表达式是匿名函数的简写形式,完整写法如下
    11. var result = list.Where(delegate (string s) {
    12. return s.Contains("c");
    13. });
  2. 标准的查询操作符

    1. ** 过滤操作符
    2. > Where操作符
    3. 在查询语句中使用where在后面加上过滤条件(函数)就可以了
    4. List<string> list = new List<string>() { "a", "b", "cb", "dc", "ae" };
    5. Func<string, bool> isFilter = s => s.Contains("a");
    6. var result = from s in list where isFilter(s) select s;
    7. 在扩展方法中使用where有两个重载
    8. 不带索引的重载
    9. List<string> list = new List<string>() { "a", "b", "cb", "dc", "e" };
    10. var result = list.Where(s => s.Contains("c"));
    11. 带索引的重载
    12. List<string> list = new List<string>() { "a", "b", "cb", "dc", "e" };
    13. int isum = 0;
    14. IEnumerable<string> result = list.Where((s, i) =>
    15. {
    16. if (s.Contains("c"))
    17. {
    18. isum++;
    19. return true;
    20. }
    21. return false;
    22. }).ToList(); // 这里不写ToList()的话linq语句不执行
    23. return Ok(isum);
    24. 无论是查询语句还是扩展方法,where都可以使用多个
    25. IEnumerable<string> result = list.Where(s => s.Contains("c")).Where(s => s.Contains("b"));
    26. > OfType操作符
    27. 使用OfType操作符可以根据数据类型来过滤数据
    28. 在查询语句中使用
    29. ArrayList list = new ArrayList() { 2, "a", 5};
    30. var result = from s in list.OfType<int>() select s; // 将ArrayList所有的int类型数据筛选出来
    31. 在扩展方法中使用
    32. ArrayList list = new ArrayList() { 2, "a", 5};
    33. var result = list.OfType<string>();
    34. ** 排序操作符
    35. > OrderBy语句
    36. 根据指定的字段升序或者降序排序
    37. IList<TestClass> list = new List<TestClass>() {
    38. new TestClass() { StudentID = 1, StudentName = "John", Age = 18 } ,
    39. new TestClass() { StudentID = 2, StudentName = "Steve", Age = 15 } ,
    40. new TestClass() { StudentID = 3, StudentName = "Bill", Age = 15 } ,
    41. new TestClass() { StudentID = 4, StudentName = "Ram" , Age = 20 } ,
    42. new TestClass() { StudentID = 5, StudentName = "Ron" , Age = 19 }
    43. };
    44. 在查询语句中使用
    45. var result = from s in list orderby s.Age select s; // 默认是升序排序,ascending可以指定也可以不写
    46. var result = from s in list orderby s.Age descending select s; // 指定descending实现降序
    47. 可以指定多条列进行排序
    48. var result = from s in list orderby s.Age, s.StudentID descending select s;
    49. 如果s.Age是相同的,那么根据s.StudentID对相同的数据进行排序
    50. 在扩展语句中使用
    51. 重载一,使用默认规则实现简单的升序排序
    52. var result = list.OrderBy(s => s.Age); // 根据Age字段进行升序排序,不支持降序
    53. 重载二,可以传递IComparer泛型实例,实现自定义排序规则
    54. 先定义一个实现IComparer的类
    55. public class CompareClass : IComparer<string>
    56. {
    57. public int Compare(string x, string y)
    58. {
    59. string str1 = x.Substring(1, 1);
    60. string str2 = y.Substring(1, 1);
    61. return int.Parse(str1).CompareTo(int.Parse(str2)); // 升序,如果调换str1和str2的位置,可以实现降序
    62. }
    63. }
    64. 实现排序
    65. IList<TestClass> list = new List<TestClass>() {
    66. new TestClass() { StudentID = 1, StudentName = "A3_John", Age = 18 } ,
    67. new TestClass() { StudentID = 2, StudentName = "A4_Steve", Age = 15 } ,
    68. new TestClass() { StudentID = 3, StudentName = "A2_Bill", Age = 25 } ,
    69. new TestClass() { StudentID = 4, StudentName = "A5_Ram" , Age = 20 } ,
    70. new TestClass() { StudentID = 5, StudentName = "A6_Ron" , Age = 19 }
    71. };
    72. var result = list.OrderBy(s => s.StudentName, new CompareClass());
    73. > OrderByDescending语句
    74. 根据指定的字段降序排序,只能在扩展方法中使用
    75. var result = list.OrderByDescending(s => s.Age);
    76. > ThenBy语句
    77. 用于二级排序的升序,只能在扩展方法中使用
    78. var result = list.OrderBy(s => s.Age).ThenBy(s => s.StudentID);
    79. s.Age排序后的结果中的相同项按照s.StudentID进行升序排序
    80. > ThenByDescending语句
    81. 用于二级排序的降序,只能在扩展方法中使用
    82. var result = list.OrderBy(s => s.Age).ThenByDescending(s => s.StudentID);
    83. s.Age排序后的结果中的相同项按照s.StudentID进行降序排序
    84. > Reverse语句
    85. 反序排序,只能用于扩展方法中
    86. var result = list.Reverse();
    87. 对原始集合进行反转排序操作
    88. ** 分组操作符
    89. > GroupBy操作符
    90. GroupBy根据指定的列将相同项分成一组,返回的结果是IEnumerable <IGrouping<TKey, TSource>>类型
    91. 每组是IGrouping<TKey, TSource>类型,TKey是键的类型,TSource是结果集合的类型
    92. IList<TestClass> list = new List<TestClass>() {
    93. new TestClass() { StudentID = 1, StudentName = "A3_John", Age = 18 } ,
    94. new TestClass() { StudentID = 2, StudentName = "A4_Steve", Age = 15 } ,
    95. new TestClass() { StudentID = 3, StudentName = "A2_Bill", Age = 15 } ,
    96. new TestClass() { StudentID = 4, StudentName = "A5_Ram" , Age = 20 } ,
    97. new TestClass() { StudentID = 5, StudentName = "A6_Ron" , Age = 20 }
    98. };
    99. 在查询语句中使用
    100. var result = from s in list group s by s.Age;
    101. foreach(var ageGroup in result)
    102. {
    103. Trace.WriteLine(ageGroup.Key); // Key是分组的Age值
    104. foreach( TestClass s in ageGroup)
    105. {
    106. // ...
    107. }
    108. }
    109. 在扩展方法中使用
    110. var result = list.GroupBy(s => s.Age);
    111. > ToLookup操作符
    112. 只能在扩展方法中使用
    113. var result = list.ToLookup(s => s.Age);
    114. ToLookupGroupBy功能是一样的,但是ToLookup是立即执行的,而GroupBy之后的result是没有值的,只会在使用的时候执行并存储数据
    115. ** 连接操作符
    116. > Join操作符
    117. 作用和sql inner Join 一样
    118. 在扩展方法中使用
    119. 例子一:
    120. 第一个参数是inner表,第二个参数是outer表的列,第三个参数是inner表的列,第四个参数是结果集的格式
    121. 当第二个参数和第三个参数对应的列值相同,那么数据筛选出来,然后经过第四个参数处理后返回
    122. List<string> list1 = new List<string>() { "a", "b", "c", "d", "e" };
    123. List<string> list2 = new List<string>() { "a", "b", "e", "f", "a" };
    124. var result = list1.Join(list2, s1 => s1, s2 => s2, (s1, s2) => s1);
    125. 例子二:
    126. IList<Demo1> studentList1 = new List<Demo1>() {
    127. new Demo1() { StudentID = 1, StudentName = "John", StandardID =1 },
    128. new Demo1() { StudentID = 2, StudentName = "Moin", StandardID =1 },
    129. new Demo1() { StudentID = 3, StudentName = "Bill", StandardID =2 },
    130. new Demo1() { StudentID = 4, StudentName = "Ram" , StandardID =2 },
    131. new Demo1() { StudentID = 5, StudentName = "Ron" }
    132. };
    133. IList<Demo2> standardList2 = new List<Demo2>() {
    134. new Demo2(){ StandardID = 1, StandardName="Standard 1"},
    135. new Demo2(){ StandardID = 2, StandardName="Standard 2"},
    136. new Demo2(){ StandardID = 3, StandardName="Standard 3"}
    137. };
    138. var result = studentList1.Join(standardList2, s1 => s1.StandardID, s2 => s2.StandardID, (s1, s2) =>
    139. {
    140. return new
    141. {
    142. StudentName = s1.StudentName,
    143. StandardName = s2.StandardName
    144. };
    145. });
    146. 在查询语句中使用
    147. 使用上面的studentList1standardList2为例
    148. var result = from s1 in studentList1
    149. join s2 in standardList2 on s1.StandardID equals s2.StandardID
    150. select new
    151. {
    152. StudentName = s1.StudentName,
    153. standardName = s2.StandardName
    154. };
    155. > GroupJoin操作符
    156. 作用和sql left join,right join类似
    157. 在扩展方法中使用
    158. 还是使用上面的studentList1standardList2为例
    159. var result = studentList1.GroupJoin(standardList2, s1 => s1.StandardID, s2 => s2.StandardID, (s1, s2Obj) =>
    160. {
    161. return new
    162. {
    163. studentName = s1.StudentName,
    164. standardName = s2Obj // s2Obj自动将 s2 转成 IEnumerable类型
    165. };
    166. });
    167. 在查询语句中使用
    168. var result = from s1 in studentList1
    169. join s2 in standardList2 on s1.StandardID equals s2.StandardID into s3
    170. select new
    171. {
    172. standard = s3,
    173. studentName = s1.StudentName
    174. };
    175. ** 投影操作符
    176. > select操作符
    177. sql中的select类似
    178. 在查询语句中使用
    179. var result = from item in someList select item;
    180. var result = from item in someList select new { column1 = item.Name, column2 = item.Age };
    181. 在扩展方法中使用
    182. 在扩展方法中Select方法仅仅用来格式化数据,在查询数据时是可选项
    183. var result = list.Select(s => new
    184. {
    185. Name = s.StudentName,
    186. Age = s.Age
    187. });
    188. > SelectMany方法
    189. SelectMany方法只能在扩展方法中使用
    190. SelectMany的作用是将指定列对应的IEnumerable列值合并成一个集合,用法如下
    191. 定义两个类
    192. public class Students
    193. {
    194. public string Name { get; set; }
    195. public int Age { get; set; }
    196. }
    197. public class ClassNames
    198. {
    199. public IEnumerable<Students> students { get; set; }
    200. public string Name { get; set; }
    201. }
    202. 使用SelectMany
    203. List<ClassNames> selectManyTest = new List<ClassNames>() { };
    204. selectManyTest.Add(new ClassNames() { students = new List<Students>() { new Students() { Name = "小张", Age = 11 } }, Name = "班级一" });
    205. selectManyTest.Add(new ClassNames() { students = new List<Students>() { new Students() { Name = "小王", Age = 21 } }, Name = "班级二" });
    206. selectManyTest.Add(new ClassNames() { students = new List<Students>() { new Students() { Name = "小红", Age = 22 } }, Name = "班级三" });
    207. var result = selectManyTest.SelectMany(s => s.students);
    208. result的结果 [{"Name":"小张","Age":11},{"Name":"小王","Age":21},{"Name":"小红","Age":22}]
    209. 这种用法其实和Select的作用是一致的 var result = selectManyTest.Select(s => s.students); 关键是下面的这种用法
    210. var result = selectManyTest.SelectMany(s => s.students, (s1, s2) =>
    211. {
    212. return new
    213. {
    214. 班级名称 = s1.Name,
    215. 学生姓名 = s2.Name,
    216. 学生年龄 = s2.Age
    217. };
    218. });
    219. 结果是 [{"班级名称":"班级一","学生姓名":"小张","学生年龄":11},{"班级名称":"班级二","学生姓名":"小王","学生年龄":21},{"班级名称":"班级三","学生姓名":"小红","学生年龄":22}]
    220. 从这里可以看出SelectMany的优势是将嵌套的复杂类型综合到一个集合中
    221. ** 量词操作符
    222. IList<TestClass> studentList = new List<TestClass>() {
    223. new TestClass() { StudentID = 1, StudentName = "John", Age = 18 } ,
    224. new TestClass() { StudentID = 2, StudentName = "Steve", Age = 15 } ,
    225. new TestClass() { StudentID = 3, StudentName = "Bill", Age = 25 } ,
    226. new TestClass() { StudentID = 4, StudentName = "Ram" , Age = 20 } ,
    227. new TestClass() { StudentID = 5, StudentName = "Ron" , Age = 19 }
    228. };
    229. > ALL操作符
    230. 指定筛选条件如果元素全部满足则返回true
    231. bool result = studentList.All(s => s.Age > 18 && s.Age < 20); // false
    232. > Any操作符
    233. 指定筛选条件只要有一个满足就返回true
    234. bool result = studentList.Any(s => s.Age > 18 && s.Age < 20); // true
    235. > Contains操作符
    236. 值类型用法
    237. List<int> list = new List<int>() { 1, 2, 3, 4, 5 };
    238. bool result = list.Contains(4);
    239. 引用类型用法
    240. 引用类型默认比较的是引用,如果要实现自定义比较引用类型,就要实现一个IEqualityComparer
    241. 创建一个IEqualityComparer
    242. public class StudentComparer : IEqualityComparer<TestClass>
    243. {
    244. public bool Equals(TestClass x, TestClass y)
    245. {
    246. if (x.StudentID == y.StudentID &&
    247. x.StudentName.ToLower() == y.StudentName.ToLower() &&
    248. x.Age == y.Age)
    249. {
    250. return true;
    251. }
    252. return false;
    253. }
    254. public int GetHashCode(TestClass obj)
    255. {
    256. Trace.WriteLine(obj.GetHashCode());
    257. return obj.GetHashCode();
    258. }
    259. }
    260. 使用
    261. bool result = studentList.Contains(new TestClass() { StudentID = 2, StudentName = "Steve", Age = 15 }, new StudentComparer()); // true
    262. ** 聚合操作符
    263. linq中聚合函数不能直接使用在查询语句中,但是可以像下面这种方式使用
    264. var result = (from s in studentList where s.Age > 20 select s).Average(s => s.Age);
    265. > Aggregate操作符
    266. 用来累积结果
    267. 重载一
    268. List<string> list = new List<string> { "a", "b", "c", "d" };
    269. var result = list.Aggregate((s1, s2) =>
    270. {
    271. return s1 + s2;
    272. }); // "abcd"
    273. 重载二,需要一个seed作为初始值
    274. List<string> list = new List<string> { "a", "b", "c", "d" };
    275. var result = list.Aggregate("结果是:", (s1, s2) =>
    276. {
    277. return s1 + s2;
    278. }); // "结果是:abcd"
    279. 重载三,需要一个Func代理函数用来对计算的结果做处理
    280. List<string> list = new List<string> { "a", "b", "c", "d" };
    281. var result = list.Aggregate(String.Empty, (s1, s2) =>
    282. {
    283. return s1 += s2 + ",";
    284. }, res => res.Substring(0, res.Length - 1)); // "a,b,c,d"
    285. > Average操作符
    286. 用来计算集合中的数字值的平均值
    287. 计算由数字组成的集合的平均值
    288. List<int> list = new List<int>() { 1, 2, 3, 4, 5 };
    289. var result = list.Average();
    290. 传递lambda表达式,用来计算引用类型中的数字的平均值
    291. var result = studentList.Average(s => s.Age);
    292. > Count操作符
    293. 返回集合的元素的个数
    294. var result = studentList.Count();
    295. 返回满足给定条件的元素个数
    296. var result = studentList.Count(s => s.Age > 19);
    297. > Max操作符
    298. 返回数字集合的最大值
    299. List<int> list = new List<int>() { 1, 2, 3, 7, 4, 5, 6 };
    300. var result = list.Max(); // 最大值 7
    301. var result = list.Max(s => s * 2); // 将元素乘2后计算最大值,14
    302. 返回引用类型集合数字属性的最大值
    303. var result = studentList.Max(s => s.Age);
    304. 对于引用类型可以实现自定义的Max比较
    305. 先声明一个类,实现了 IComparable 接口
    306. public class TestClass: IComparable<TestClass>
    307. {
    308. public int StudentID { get; set; }
    309. public string StudentName { get; set; }
    310. public int Age { get; set; }
    311. public int CompareTo(TestClass other) // 用来筛选出StudentName长度最长的一项
    312. {
    313. if(this.StudentName.Length >= other.StudentName.Length)
    314. {
    315. return 1;
    316. }
    317. return 0;
    318. }
    319. }
    320. 使用
    321. IList<TestClass> studentList = new List<TestClass>() {
    322. new TestClass() { StudentID = 1, StudentName = "John", Age = 18 } ,
    323. new TestClass() { StudentID = 2, StudentName = "Steve", Age = 15 } ,
    324. new TestClass() { StudentID = 3, StudentName = "Bill", Age = 25 } ,
    325. new TestClass() { StudentID = 4, StudentName = "Ram" , Age = 20 } ,
    326. new TestClass() { StudentID = 5, StudentName = "Ron" , Age = 19 }
    327. };
    328. var result = studentList.Max(); // 直接调用Max即可
    329. Min的使用方式和Max是一直的,不再赘述
    330. > Sum操作符
    331. 返回数字集合的总和
    332. List<int> list = new List<int>() { 1, 2, 3, 7, 4, 5, 6 };
    333. var result = list.Sum(); // 返回总和
    334. var result = list.Sum(s => s * 2 + 1); // 返回每一项乘2加1后的总和
    335. 返回应用类型集合数字属性的总和
    336. var result = studentList.Sum(s => s.Age); // 计算年龄的总和
    337. var result = studentList.Sum(s => {
    338. if(s.Age > 18)
    339. {
    340. return 1;
    341. }
    342. return 0;
    343. }); // 计算年龄大于18的人数
    344. ** 元素操作符
    345. List<int> intList = new List<int>() { 10, 21, 30, 45, 50, 87 };
    346. > ElementAt操作符
    347. 根据索引找出元素,超出范围会报错
    348. var result = intList.ElementAt(1);
    349. > ElementAtOrDefault操作符
    350. 根据索引找出元素,超出范围返回默认值,整数默认值是0,字符串默认值是null
    351. var result = intList.ElementAtOrDefault(9);
    352. > First操作符
    353. 返回第一个元素或者第一个满足条件的元素,如果给定的集合是空的,或者没有一个元素满足条件,那么会报错
    354. var result = intList.First(); // 返回集合中的第一个元素
    355. var result = intList.First(s => s > 30); // 返回满足条件的第一个元素
    356. Last的用法和First一致
    357. > FirstOrDefault操作符
    358. 返回第一个元素或者第一个满足条件的元素,如果给定的集合是空的,或者没有一个元素满足条件那么返回默认值
    359. 用法和上面一样
    360. LastOrDefault的用法和FirstOrDefault一致
    361. > Single操作符
    362. 返回集合中的唯一一个元素,或者指定条件后唯一一个元素,如果没有元素或者多于一个元素那么报错
    363. List<int> intList = new List<int>() { 10 };
    364. var result = intList.Single();
    365. > SingleOrDefault操作符
    366. 作用和Single类似,如果没有找到元素,那么返回默认值,然而,如果有多个元素那么同样报错
    367. List<int> intList = new List<int>() { 10,20 };
    368. var result = intList.SingleOrDefault(s => s > 10);
    369. ** 相等运算符
    370. > SequenceEqual
    371. 用于比较两个集合中的元素是否相等,如果元素是值类型,那么比较元素的值和顺序,如果是引用类型那么比较值的引用
    372. 值类型比较
    373. List<int> intList1 = new List<int>() { 10,20 };
    374. List<int> intList2 = new List<int>() { 10, 20 };
    375. var result = intList1.SequenceEqual(intList2); // true
    376. 引用类型比较
    377. List<TestClass> TestList1 = new List<TestClass>() { new TestClass() { StudentID = 1, StudentName = "John", Age = 18 } };
    378. List<TestClass> TestList2 = new List<TestClass>() { new TestClass() { StudentID = 1, StudentName = "John", Age = 18 } };
    379. var result = TestList1.SequenceEqual(TestList2); // false
    380. 自定义引用类型比较
    381. 如果不想比较引用类型的时候比较引用地址,那么可以使用自定义比较
    382. 首先,创建一个实现了IEqualityComparer接口的类
    383. private class SequenceEqualComparer : IEqualityComparer<TestClass>
    384. {
    385. public bool Equals(TestClass x, TestClass y)
    386. {
    387. if(x.StudentID == y.StudentID && x.StudentName == y.StudentName && x.Age == y.Age)
    388. {
    389. return true;
    390. }
    391. return false;
    392. }
    393. public int GetHashCode(TestClass obj)
    394. {
    395. return obj.GetHashCode();
    396. }
    397. }
    398. 使用
    399. List<TestClass> TestList1 = new List<TestClass>() { new TestClass() { StudentID = 1, StudentName = "John", Age = 18 } };
    400. List<TestClass> TestList2 = new List<TestClass>() { new TestClass() { StudentID = 1, StudentName = "John", Age = 18 } };
    401. var result = TestList1.SequenceEqual(TestList2, new SequenceEqualComparer()); // true
    402. ** 串联运算符
    403. > Concat运算符
    404. 用于连接两个集合
    405. var result = TestList1.Concat(TestList2);
    406. ** 生成运算符
    407. > DefaultIfEmpty操作符
    408. 如果调用此方法的集合是空的则返回一个新的集合,新集合包含一个默认值元素
    409. 不指定默认值
    410. List<string> list = new List<string>();
    411. var result = list.DefaultIfEmpty(); // 结果 [null]
    412. 指定默认值
    413. var result = list.DefaultIfEmpty("haha"); // 结果 ["haha"]
    414. 本质
    415. DefaultIfEmpty本质作用是将一个集合拷贝了一份,如果集合是空的自动填充一个默认值
    416. List<string> list = new List<string>() { "a" };
    417. var temp = list.DefaultIfEmpty("haha");
    418. var result = temp == list; // false
    419. > Empty, Range, Repeat 操作符
    420. 这三个运算符不是IEnumerable IQueryable的扩展方法,而是Enumerable的静态方法
    421. Empty操作符
    422. 返回一个空的集合
    423. var result = (Enumerable.Empty<string>()).GetType().Name; // "String[]"
    424. Range操作符
    425. 返回一个集合,元素从指定的数字开始,按照指定的个数依次递增
    426. var result = Enumerable.Range(10, 10); // [10,11,12,13,14,15,16,17,18,19]
    427. Repeat操作符
    428. 返回一个集合,元素是指定个数的相同的指定元素
    429. var result = Enumerable.Repeat<string>("a", 10); // ["a","a","a","a","a","a","a","a","a","a"]
    430. ** 集操作符
    431. > Distinct
    432. 取出集合中重复项,并返回一个新的集合
    433. 对值类型集合的操作
    434. List<string> list = new List<string>() { "a", "b", "c", "d", "b", "c" };
    435. var result = list.Distinct(); // ["a","b","c","d"]
    436. 对引用类型集合的操作,默认无效,需要自己实现IEqualityComparer
    437. 首先实现IEqualityComparer
    438. Equals,GetHashCode方法会自动调用,当GetHashCode返回的整数(引用)不一致,那么会执行Equals方法
    439. private class DistinctComparer : IEqualityComparer<TestClass>
    440. {
    441. public bool Equals(TestClass x, TestClass y)
    442. {
    443. if(x.StudentID == y.StudentID && x.StudentName == y.StudentName && x.Age == y.Age)
    444. {
    445. return true;
    446. }
    447. return false;
    448. }
    449. public int GetHashCode(TestClass obj)
    450. {
    451. return obj.StudentID.GetHashCode(); // 注意,表示如果 StudentID的GetHashCode 相同,那么过滤掉这个数据
    452. }
    453. }
    454. 使用
    455. List<TestClass> studentList = new List<TestClass>() {
    456. new TestClass() { StudentID = 1, StudentName = "John", Age = 18 } ,
    457. new TestClass() { StudentID = 1, StudentName = "John", Age = 18 } ,
    458. new TestClass() { StudentID = 2, StudentName = "Steve", Age = 15 }
    459. };
    460. var result = studentList.Distinct(new DistinctComparer());
    461. > Except
    462. 返回一个新的集合,集合的成员是list1list2中不存在的元素
    463. 对值类型集合的操作
    464. List<string> list1 = new List<string>() { "a", "b", "c" };
    465. List<string> list2 = new List<string>() { "c", "d", "a" };
    466. var result = list1.Except(list2); // ["b"]
    467. 对引用类型集合的操作,同样也要自己实现IEqualityComparer
    468. 创建一个IEqualityComparer类,和上面一模一样
    469. private class ExceptComparer : IEqualityComparer<TestClass>
    470. {
    471. public bool Equals(TestClass x, TestClass y)
    472. {
    473. if (x.StudentID == y.StudentID && x.StudentName == y.StudentName && x.Age == y.Age)
    474. {
    475. return true;
    476. }
    477. return false;
    478. }
    479. public int GetHashCode(TestClass obj)
    480. {
    481. return obj.StudentID.GetHashCode(); // 注意,表示如果 StudentID的GetHashCode 相同,那么过滤掉这个数据
    482. }
    483. }
    484. 使用
    485. List<TestClass> studentList1 = new List<TestClass>() {
    486. new TestClass() { StudentID = 1, StudentName = "John", Age = 18 } ,
    487. new TestClass() { StudentID = 1, StudentName = "John", Age = 18 } ,
    488. new TestClass() { StudentID = 2, StudentName = "Steve", Age = 15 }
    489. };
    490. List<TestClass> studentList2 = new List<TestClass>() {
    491. new TestClass() { StudentID = 1, StudentName = "John", Age = 18 } ,
    492. new TestClass() { StudentID = 3, StudentName = "John", Age = 18 } ,
    493. new TestClass() { StudentID = 4, StudentName = "Steve", Age = 15 }
    494. };
    495. var result = studentList1.Except(studentList2, new ExceptComparer()); // [{"StudentID":2,"StudentName":"Steve","Age":15}]
    496. > Intersect
    497. 相当于取交集
    498. 值类型集合操作
    499. List<string> list1 = new List<string>() { "a", "b", "c" };
    500. List<string> list2 = new List<string>() { "c", "d", "a" };
    501. var result = list1.Intersect(list2); // ["a","c"]
    502. 引用类型集合操作,同样也是要创建IEqualityComparer类,实现和上面是一模一样,不再赘述
    503. 使用
    504. var result = studentList1.Intersect(studentList2, new IntersectComparer());
    505. // 返回结果 [{"StudentID":1,"StudentName":"John","Age":18}]
    506. > Union
    507. 将两个集合拼接起来,并且剔除掉重复项
    508. 值类型集合操作
    509. List<string> list1 = new List<string>() { "a", "b", "c", "a", "b" };
    510. List<string> list2 = new List<string>() { "c", "d", "a" };
    511. var result = list1.Union(list2); // ["a","b","c","d"]
    512. 引用类型集合操作,同样也是要创建IEqualityComparer类,实现和上面是一模一样,不再赘述
    513. 使用
    514. var result = studentList1.Union(studentList2, new UnionComparer());
    515. 返回结果如下
    516. /*
    517. [
    518. {"StudentID":1,"StudentName":"John","Age":18},
    519. {"StudentID":2,"StudentName":"Steve","Age":15},
    520. {"StudentID":3,"StudentName":"John","Age":18},
    521. {"StudentID":4,"StudentName":"Steve","Age":15}
    522. ]
    523. */
    524. ** 分区操作符
    525. > Skip操作符
    526. 过滤掉集合中指定个数的元素,返回剩余元素组成的集合
    527. List<string> list = new List<string>() { "a", "b", "c" };
    528. var result = list.Skip(2); // ["c"]
    529. > SkipWhile操作符
    530. 指定条件过滤,如果条件满足全部过滤掉,直到条件为false,返回剩余元素组成的集合
    531. List<int> list = new List<int>() { 1, 2, 5, 2, 4, 5, 6 };
    532. var result = list.SkipWhile((s, i) => s < 3); // [5,2,4,5,6]
    533. > Take操作符
    534. 功能和Skip相反,获取指定数量的元素,并返回新的集合
    535. List<string> list = new List<string>() { "a", "b", "c" };
    536. var result = list.Take(2); // ["a","b"]
    537. > TakeWhile操作符
    538. 功能和SkipWhile相反,获取满足指定条件的元素,直到条件不满足,返回新的集合
    539. List<int> list = new List<int>() { 1, 2, 5, 2, 4, 5, 6 };
    540. var result = list.TakeWhile((s, i) => s < 3); // [1,2]
    541. ** 转换运算符
    542. > AsEnumerable操作符
    543. 将集合强制转换成IEnumerable集合
    544. int[] arr = new int[] { 1, 2, 3, 4, 5 };
    545. var result = arr.AsEnumerable();
    546. > AsQueryable操作符
    547. 将集合强制转换成IQueryable集合
    548. List<int> list = new List<int>() { 1, 2, 5, 2, 4, 5, 6 };
    549. var result = list.AsQueryable();
    550. > Cast操作符
    551. 作用和AsEnumerable是一样的
    552. int[] arr = new int[] { 1, 2, 3, 4, 5 };
    553. var result = arr.Cast<int>(); 等效于 var result = (IEnumerable<int>)arr;
    554. > ToArrayToListToDictionary扩展方法
    555. To系列的操作,会强制让sql语句执行结果并且将数据缓存在本地
    556. int[] arr = new int[] { 1, 2, 3, 4, 5 };
    557. ToArray使用
    558. int[] result = arr.ToArray<int>();
    559. ToList使用
    560. List<int> result = arr.ToList<int>();
    561. ToDictionary使用
    562. var result = arr.ToDictionary<int, int>(s => s);
  3. Linq中的Expression类型

    1. FuncAction类型的委托构建的lambada表达式在编译期间会转换成可执行的代码,linq引入新的Expression类型,将lambda表达式转换成Expression树而不是可执行代码
    2. 传统写代理的方式
    3. Func<int, bool> isTest = s => s > 5;
    4. Expression写代理的方式
    5. Expression<Func<int, bool>> isTest = s => s > 5;
    6. 调用Expression代理
    7. 调用之前需要先编译一下
    8. Func<int, bool> isIWant = isTest.Compile();
    9. bool result = isIWant(3);
    10. 为什么要有表达式树?
    11. 编译的区别
    12. Func编译后的代码 {Method = {Boolean <.ctor>b__9_0(Int32)}}
    13. Expression编译后的代码 {s => (s > 5)}
    14. 很明显的感觉到,Func编译后被改了,表达式树更加的透明,你可以轻松的调用Expression的方法访问方法的每一个部分
    15. 处理代码的区别
    16. Func值适合当前程序集中运行,也就是说只适合内存中的集合,因为如果涉及数据库查询的话,数据库无法获知编译后的IL代码到底是个啥
    17. Expression表达式树,专门用来处理类似数据库的操作
    18. 执行效率
    19. Func要想操作数据库,需要借助Entity Frameworks将可执行代码编译成Sql查询字符串发送到sql server数据库中
    20. 使用Expression表达式树,可以轻松的将lambda表达式转换成Sql语句,因为Expression内置了很多属性和方法方便获取表达式的每一部分,所以执行效率更快
    21. 总之,一句话,操作数据库使用Expression更好
  4. 延迟执行linq查询

    1. linq表达式不会立即执行,而是用到了才会调用,从而保证每次使用linq时都是最新的数据
    2. 默认情况下linq的延迟加载不会有什么特殊的效果,只是简单的延迟而已,但是你可以自定义扩展方法使用yield关键字实现自己的延迟效果
    3. 首先,要定义扩展方法,需要一个顶级静态类
    4. public static class EnumerableExtensionMethodsDemo
    5. {
    6. public static IEnumerable<int> GetIWant(this List<int> test)
    7. {
    8. foreach (int item in test)
    9. {
    10. if(item > 5 && item < 10)
    11. {
    12. yield return item;
    13. }
    14. }
    15. }
    16. }
    17. 使用
    18. List<int> list = new List<int>() { 1, 2, 10, 50, 30, 5, 7, 9, 11 };
    19. var result = from s in list.GetIWant() select s;
    20. foreach (int i in result)
    21. {
    22. // 在这里才会调用result查询语句
    23. }
  5. 立即执行linq查询

    1. 上面讲到的以to开头的扩展方法,都可以让linq语句立即执行
  6. linq中使用let关键字

    1. List<string> list = new List<string>() { "sa", "rb", "bc", "sd" };
    2. var result = from s in list where s.ToLower().StartsWith("s") select s.ToLower();
    3. 上面这个查询语句中 ToLower 使用了两次,很啰嗦,可以使用let简化
    4. var result = from s in list
    5. let lowerItem = s.ToLower()
    6. where lowerItem.StartsWith("s")
    7. select lowerItem;
  7. into关键字

    1. into关键字单独使用的作用,是将上个查询语句的结果传递到下一个查询语句中,两个查询语句中的变量互不影响
    2. List<string> list = new List<string>() { "sa", "rb", "bc", "sd" };
    3. var result = from s in list
    4. where s.ToLower().StartsWith("s")
    5. select s
    6. into s
    7. where s.ToLower().EndsWith("a")
    8. select s; // ["sa"]

c# linq查询语句详细使用介绍的更多相关文章

  1. 简单的Linq查询语句

    下面我来我大家介绍几种简单的查询方式. 1.简单语法 这个LINQ语句的第一个关键字是from,from后面加的是范围变量,范围变量后加in,后加上事先实例化的模型,然后点出数据的来源. List是列 ...

  2. linq查询语句转mongodb

    && (与操作) 子表达式可以通过&&合并来查询满足所有子表达式的文档 var query = from c in collection.AsQueryable< ...

  3. C#高级知识点概要(3) - 特性、自动属性、对象集合初始化器、扩展方法、Lambda表达式和Linq查询

    1.特性(Attributes) 特性(Attributes),MSDN的定义是:公共语言运行时允许你添加类似关键字的描述声明,叫做attributes, 它对程序中的元素进行标注,如类型.字段.方法 ...

  4. C# LINQ查询表达式用法对应Lambda表达式

    C#编程语言非常优美,我个人还是非常赞同的.特别是在学习一段时间C#后发现确实在它的语法和美观度来说确实要比其它编程语言强一些(也可能是由于VS编译器的加持)用起来非常舒服,而且对于C#我觉得他最优美 ...

  5. 【总结】LINQ查询基本操作列表

    每个LINQ查询都以from子句开始,from子句包括以下两个功能. 指定查询将采用数据源. 定义一个本地变量,表示数据源中单个元素. string[] values = { "中国&quo ...

  6. LINQ中的一些查询语句格式

    LINQ的基本格式如下所示:var <变量> = from <项目> in <数据源> where <表达式> orderby <表达式> ...

  7. 浅谈sql 、linq、lambda 查询语句的区别

    浅谈sql .linq.lambda 查询语句的区别 LINQ的书写格式如下: from 临时变量 in 集合对象或数据库对象 where 条件表达式 [order by条件] select 临时变量 ...

  8. ES 常用的查询语句介绍

    elasticsearch定义了两种查询方式: 一.索引(index).type.document 相关语句 1.列出所有索引的状态 GET /_cat/indices?v health status ...

  9. 这里我们介绍的是 40+ 个非常有用的 Oracle 查询语句,主要涵盖了日期操作,获取服务器信息,获取执行状态,计算数据库大小等等方面的查询。这些是所有 Oracle 开发者都必备的技能,所以快快收藏吧!

    日期/时间 相关查询 获取当前月份的第一天 运行这个命令能快速返回当前月份的第一天.你可以用任何的日期值替换 “SYSDATE”来指定查询的日期. SELECT TRUNC (SYSDATE, 'MO ...

随机推荐

  1. linux基础(1)-yum源配置

    用linux将近一年了,开始学的东西因为没经常用都忘记了,现在将笔记的东西慢慢整理成自己的博客,也算是看着自己进步.有些东西从他人博客笔记学的,有些是从视频学的,有些是自己填坑积累的. 在linux下 ...

  2. 比较好的sql写法

    DECLARE @beginTime VARCHAR(20)= '2017-11-13 00:00:00';DECLARE @endTime VARCHAR(20)= '2017-11-13 23:0 ...

  3. Mssql 比较好的写法

    DECLARE @date DATETIME= '2016-11-01'; DECLARE @date2 DATETIME= DATEADD(day, 1, @date); Declare @1 Ta ...

  4. BZOJ2764 [JLOI2011]基因补全

    Description 在 生物课中我们学过,碱基组成了DNA(脱氧核糖核酸),他们分别可以用大写字母A,C,T,G表示,其中A总与T配对,C总与G配对.两个碱基序列能相互 匹配,当且仅当它们等长,并 ...

  5. python3 列表属性

    1.合并 >>> l1=[1,2,3,'e']>>> l2=['f',34,'feel']>>> l1+l2[1, 2, 3, 'e', 'f', ...

  6. RNN、LSTM、Char-RNN 学习系列(一)

    RNN.LSTM.Char-RNN 学习系列(一) zoerywzhou@gmail.com http://www.cnblogs.com/swje/ 作者:Zhouw  2016-3-15 版权声明 ...

  7. 在Java中定义常量

    方法一采用接口(Interface)的中变量默认为static final的特性. 方法二采用了Java 5.0中引入的Enum类型. 方法三采用了在普通类中使用static final修饰变量的方法 ...

  8. Nhibernate系列学习之(四) 数据操作

    数据操作,在这里主要介绍INSERT.UPDATE.DELETE.我们在使用NHibernate的时候,如果只是查询数据,不需要改变数据库的值,那么是不需要提交或者回滚到数据库的. 一.INSERT ...

  9. spring学习-4

    bean的作用域 使用bean的scope属性来配置bean的作用域 scope="singleton":默认是单例模式即容器初始化创建bean实例,在整个容器的生命周期内只创建这 ...

  10. 【剑指offer】删除链表中重复的节点,C++实现(链表)

    0.简介       本文是牛客网<剑指offer>笔记. 1.题目 在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针.例如,链表1-> ...