第十二节:Lambda、linq、SQL的相爱相杀(1)
一. 谈情怀
Lambda、Linq、SQL伴随着我的开发一年又一年,但它们三者并没有此消彼长,各自占有这一定的比重,起着不可替代的作用。
相信我们最先接触的应该就是SQL了,凡是科班出身的人,大学期间都会学习SQL Server数据库,当然也会学习SQL语言了(顺便吐槽一下,学校用SQL Server版本真老,好像是2005,我现在都用2016了),补充一点:主流数据库像SQL Sever、MySQL、Oracle某些语句是不同的,在后面介绍分页的时候会有体现。
(1). SQL:是关系型数据库标准语言,其特点:简单,灵活,功能强大。(详细的概念介绍见 数据库概述)
后来在工作中接触到了强大的ORM框架EF,发现了一种写法 db.Sys_UserInfor.Where(u => u.userAccount == "admin").ToList(); 彻底颠覆了我的三观,查询数据库,竟然可以这么简单,后来查询了一下,这个东西叫Lambda。
(2). Lambda:是比匿名方法更简洁的一种语法,包括 Lambda表达式 和 Lambda语句 。
补充Lambad的发展历史:
A. 内置委托: new Func<string, int>(delegate(string str) { return str.Length; });
B. 匿名方法: delegate(string str){return str.Length;}
C. lambda语句: (string str)=>{return str.Length;}
D. lambda表达式: (string str)=> str.Length
E.让编译器推断类型: (str)=> str.Length
F. 去掉不必要的括弧: str=> str.Length
注意:Lambda语句 和 Lambda表达式 的区别在于,前者在 =>右边有一个语句块(大括号),而后者只有一个表达式(没有return 和大括号)。Lambda本身无类型,所以不能赋值给 var 变量。编译时会生成一个静态方法, 然后再实例化成委托传递。
1. Lambda表达式: list.FindAll(d => d.Id > 2); 又名:点标记。
2. Lambda语句:list.ForEach(d => { if (d.Id > 2) { Response.Write(d.ToString()); } });
(3). Linq:是最接近SQL语言的一种查询表达式,又称语言集成查询,它是C# 3.0 时代的产物。
它与SQL写法上的本质区别是: linq是以from开头 select 或group by结尾。
二. 数据准备
我们准备两张表 用户表Sys_UserInfor和用户登录记录表LoginRecords。
表结构:
表数据:
三. Lambda开篇
1. Where用法
Where用法相对比较简单,多个并列条件可以在一个Where中用&&符号链接,也可以写过个Where,最终的结果结果相同
1 DataDBEntities db = new DataDBEntities();2 #region 01-where用法3 {4 //1. where用法5 //1.1 查询账号为admin的用户信息6 Console.WriteLine("---------------------------- 1. where用法 ----------------------------------------");7 Console.WriteLine("---------------------------- 1.1 查询账号为admin的用户信息 ----------------------------------------");8 List<Sys_UserInfor> sUserList1 = db.Sys_UserInfor.Where(u => u.userAccount == "admin").ToList();9 foreach (var item in sUserList1)
10 {
11 Console.WriteLine("用户名:{0},用户账号:{1},用户年龄:{2},用户性别:{3}", item.userName, item.userAccount, item.userAge, item.userSex);
12 }
13 //1.2 查询账号为中包含admin且性别为男的用户信息
14 Console.WriteLine("---------------------------- 1.2 查询账号为中包含admin且性别为男的用户信息 ----------------------------------------");
15 List<Sys_UserInfor> sUserList2 = db.Sys_UserInfor.Where(u => u.userAccount.Contains("admin") && u.userSex == "男").ToList();
16 foreach (var item in sUserList2)
17 {
18 Console.WriteLine("用户名:{0},用户账号:{1},用户年龄:{2},用户性别:{3}", item.userName, item.userAccount, item.userAge, item.userSex);
19 }
20 }
21 #endregion
2. Select用法
Select中可以查询所有数据,也可以查询指定字段。
当查询所有数据的时候可以这么写:var sUserList22 = db.Sys_UserInfor.Where(u => u.userAccount.Contains("admin")).Select(u=>u).ToList(); 或者直接可以省略Select部分。
当查询部分数据的时候: 可以用匿名类,也可以用实体。
即使用匿名类的时候,也可以指定列名,不指定的话,默认和数据库的列名一致。
1 #region 02-select用法 (匿名类和非匿名类写法)2 {3 //2. select用法 (匿名类和非匿名类写法)4 //2.1 查询账号中包含 admin 的用户的 姓名、年龄和性别 三条信息 (匿名类的写法,自动生成匿名类名称)5 Console.WriteLine("---------------------------- 2. select用法 (匿名类和非匿名类写法) ----------------------------------------");6 Console.WriteLine("-------------2.1 查询账号中包含 admin 的用户的 姓名、年龄和性别 三条信息 (匿名类的写法)-------------------------");7 var sUserList1 = db.Sys_UserInfor.Where(u => u.userAccount.Contains("admin")).Select(u => new8 {9 u.userName,
10 u.userAge,
11 u.userSex
12 }).ToList();
13 sUserList1.ForEach(u =>
14 {
15 Console.WriteLine("用户名:{0},用户年龄:{1},用户性别:{2}", u.userName, u.userAge, u.userSex);
16 });
17 //2.2 查询账号中包含 admin 的用户的 姓名、年龄和性别 三条信息 (匿名类的写法,指定匿名类名称)
18 Console.WriteLine("---------2.2 查询账号中包含 admin 的用户的 姓名、年龄和性别 三条信息 (匿名类的写法 指定匿名类名称)--------");
19 var sUserList2 = db.Sys_UserInfor.Where(u => u.userAccount.Contains("admin")).Select(u => new
20 {
21 Name = u.userName,
22 Age = u.userAge,
23 Sex = u.userSex
24 }).ToList();
25 sUserList2.ForEach(u =>
26 {
27 Console.WriteLine("用户名:{0},用户年龄:{1},用户性别:{2}", u.Name, u.Age, u.Sex);
28 });
29 //2.3 查询账号中包含 admin 的用户的 姓名、年龄和性别 三条信息 (非匿名类的写法)
30 Console.WriteLine("-------------2.3 查询账号中包含 admin 的用户的 姓名、年龄和性别 三条信息 (非匿名类的写法)-------------------------");
31 List<newUserInfor> sUserList3 = db.Sys_UserInfor.Where(u => u.userAccount.Contains("admin")).Select(u => new newUserInfor
32 {
33 newName = u.userName,
34 newAge = u.userAge,
35 newSex = u.userSex
36 }).ToList();
37 sUserList3.ForEach(u =>
38 {
39 Console.WriteLine("用户名:{0},用户年龄:{1},用户性别:{2}", u.newName, u.newAge, u.newSex);
40 });
41 }
42 #endregion
3. OrderBy(OrderByDescending、ThenBy、ThenByDescending)用法
排序的用法在Lambda、Linq和SQL中相差还是很大的,写法的关键字截然不同。
在Lambda中:升序: OrderBy→ThenBy→ThenBy
降序: OrderByDescending→ThenByDescending
先升序后降序再升序: OrderBy→ThenByDescending→ThenBy
1 #region 03-OrderBy(OrderByDescending、ThenBy、ThenByDescending)用法2 {3 //3. OrderBy(OrderByDescending、ThenBy、ThenByDescending)用法 (单条件升降序、多条件综合排序)4 //3.1 查询delflag 为1 的所有用户信息,按照时间升序排列5 Console.WriteLine("------3. OrderBy(OrderByDescending、ThenBy、ThenByDescending)用法 (单条件升降序、多条件综合排序)-------------");6 Console.WriteLine("--------------------- 3.1 查询delflag 为1 的所有用户信息,按照时间升序排列 ------------------------------");7 List<Sys_UserInfor> sUserList1 = db.Sys_UserInfor.Where(u => u.delFlag == 1).OrderBy(u => u.addTime).ToList();8 foreach (var item in sUserList1)9 {
10 Console.WriteLine("用户名:{0},用户账号:{1},用户年龄:{2},用户性别:{3},创建时间:{4}", item.userName, item.userAccount, item.userAge, item.userSex, item.addTime);
11 }
12 //3.2 查询delflag 为1 的所有用户信息,先按照时间升序排列,再按照年龄降序
13 Console.WriteLine("---------------3.2 查询delflag 为1 的所有用户信息,先按照时间升序排列,再按照年龄降序----------------------");
14 List<Sys_UserInfor> sUserList2 = db.Sys_UserInfor.Where(u => u.delFlag == 1).OrderBy(u => u.addTime).ThenByDescending(u => u.userAge).ToList();
15 foreach (var item in sUserList2)
16 {
17 Console.WriteLine("用户名:{0},用户账号:{1},用户年龄:{2},用户性别:{3},创建时间:{4}", item.userName, item.userAccount, item.userAge, item.userSex, item.addTime);
18 }
19 }
20 #endregion
4. join连接查询
这里展示的类似全连接的查询,在多表查询,特别是内连接和外链接方面明显不如 Linq和SQL。
1 #region 04-join连接查询(作用仅限与此么?)2 {3 //4. join连接查询(匿名类和非匿名类)4 Console.WriteLine("-------------------- 4. join连接查询(匿名类和非匿名类)------------------------");5 var sUserList = db.Sys_UserInfor;6 var sLoginRecordsList = db.LoginRecords;7 var newList = sUserList.Join(sLoginRecordsList, u => u.id, p => p.userId, (u, p) => new8 {9 UserName = u.userName,
10 LoginIp = p.loginIp,
11 LoginCity = p.loginCity,
12 LoginTime = p.loginTime
13
14 }).ToList();
15 newList.ForEach(a => Console.WriteLine("姓名:{0},登录IP:{1},登录城市:{2},登录时间:{3}", a.UserName, a.LoginIp, a.LoginCity, a.LoginTime));
16
17 //非匿名类的情况与上述select中的用法相似
18 }
19 #endregion
5. GroupBy分组(匿名类写法)
这里建议使用var类型接收,原类型太难记忆了,记住一点Lambda和Linq可以把分组依据和分组后对应的数据一次性全部拿出来,但是SQL中分组只能查询分组的依据和使用聚合函数处理其它字段,不能直接查询非分组依据以外的字段。
1 #region 05-GroupBy分组(匿名类写法)2 {3 //5. GroupBy分组(需要重点看一下)4 //5.1 根据用户的性别进行分类,然后将不同性别的用户信息输出来5 Console.WriteLine("-------------------- 5. GroupBy分组------------------------");6 Console.WriteLine("-------------------- 5.1 根据用户的性别进行分类,然后将不同性别的用户信息输出来------------------------");7 var sUserListGroup = db.Sys_UserInfor.GroupBy(u => u.userSex).ToList();8 foreach (var group in sUserListGroup)9 {
10 Console.WriteLine("性别为:{0}", group.Key); //分组依据的字段内容
11 foreach (var item in group)
12 {
13 Console.WriteLine("用户名:{0},用户账号:{1},用户年龄:{2},用户性别:{3}", item.userName, item.userAccount, item.userAge, item.userSex);
14 }
15 }
16 //5.2 根据用户性别进行分类,然后将不同性别的年龄大于等于21岁的用户信息输出来
17 Console.WriteLine("-------------5.2 根据用户性别进行分类,然后将不同性别的年龄大于等于21岁的用户信息输出来-------------------");
18 var sUserListGroup2 = db.Sys_UserInfor.Where(u => u.userAge >= 21).GroupBy(u => u.userSex).ToList();
19 foreach (var group in sUserListGroup2)
20 {
21 Console.WriteLine("性别为:{0}", group.Key); //分组依据的字段内容
22 foreach (var item in group)
23 {
24 Console.WriteLine("用户名:{0},用户账号:{1},用户年龄:{2},用户性别:{3}", item.userName, item.userAccount, item.userAge, item.userSex);
25 }
26 }
27 }
28 #endregion
6. Skip和Take用法
这里结合Skip和Take写分页,太方便了,分页公式:
data.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();
补充MySQL数据中特有的分页,也很方便,分页公式:SELECT * FROM 表名 LIMIT (pageIndex-1)*pageSize,pageSize .
1 #region 06-Skip和Take用法2 {3 //6. Skip和Take 分页用法4 //skip表示跳过多少条,Take表示取多少条5 //6.1 根据时间降序排列,取第2和第3条数据(即先排序,然后跨过1条,取2条数据)6 Console.WriteLine("--------------------6. Skip和Take 分页用法------------------------");7 Console.WriteLine("---------6.1 根据时间降序排列,取第2和第3条数据(即先排序,然后跨过1条,取2条数据)---------");8 var sUserList = db.Sys_UserInfor.OrderByDescending(u => u.addTime).Skip(1).Take(2).ToList();9 sUserList.ForEach(u =>
10 {
11 Console.WriteLine("用户名:{0},用户年龄:{1},用户性别:{2},创建时间:{3}", u.userName, u.userAge, u.userSex, u.addTime);
12 });
13
14 // 6.2 分页公式
15 // 每页两条数据,根据时间降序,取第三页的所有数据
16 Console.WriteLine("---------6.2 每页两条数据,根据时间降序,取第三页的所有数据---------");
17 var sUserList2 = GetDataByIndex(db.Sys_UserInfor.OrderByDescending(u => u.addTime).ToList(), 3, 2);
18 sUserList2.ForEach(u =>
19 {
20 Console.WriteLine("用户名:{0},用户年龄:{1},用户性别:{2},创建时间:{3}", u.userName, u.userAge, u.userSex, u.addTime);
21 });
22 }
23 #endregion
1 #region 分页公式
2 static List<Sys_UserInfor> GetDataByIndex(List<Sys_UserInfor> data, int pageIndex, int pageSize)
3 {
4 return data.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();
5 }
6 #endregion
7. GroupJoin外连接查询(相当于left Join)
1 #region 06-GroupJoin外连接查询(相当于left Join)2 {3 Console.WriteLine("-------------------- 06-GroupJoin多表关联分组------------------------");4 Console.WriteLine("--------------------根据性别分组,输出相同性别的用户和登录城市 ------------------------");5 var list = db.Sys_UserInfor.GroupJoin(db.LoginRecord2, (Sys_UserInfor a) => a.id, (LoginRecord2 b) => b.userId, (m,n) => new6 {7 m.userName,8 n9 }).ToList();
10
11 foreach (var item in list)
12 {
13 var userName = item.userName;
14 foreach (var cItem in item.n.ToList())
15 {
16 Console.WriteLine("用户名为{0}的用户的登录城市是:{1},登录时间是:{2}", userName, cItem.loginCity,cItem.loginTime);
17 }
18 }
19 }
20 #endregion
第十二节:Lambda、linq、SQL的相爱相杀(1)相关推荐
- 第十四节:Lambda、linq、SQL的相爱相杀(3)
一. SQL 开篇 1. where用法 1 #region 封装EF调用SQL语句查询 2 public static List<T> ExecuteQuery<T>(str ...
- 第十三节:Lambda、linq、SQL的相爱相杀(2)
一. Linq开篇 1.Where用法 linq中where的用法与SQL中where的用法基本一致. 1 #region 01-where用法2 {3 //1. where用法4 //1.1 查询账 ...
- 阿里云CDN技术掌舵人文景:相爱相杀一路狂奔的这十年
提到阿里云CDN,不得不提技术掌舵人姚伟斌(文景),虽然他不是团队中最"老"的同学,但他却历经了淘宝业务发展最为飞速的几年,见证了从最初服务淘宝和集团内部的CDN,到如今国内服务客 ...
- 人类一败涂地电脑版_iOS账号分享 |人类一败涂地 我们继续相爱相杀,PC大火游戏移植!...
「 改变能改变的一切,接受不能改变的一切!」 ▼ PC 平台上爆火的多人物理益智游戏<人类一败涂地>(Human: Fall Flat)移动版正式登陆 iOS 和 Android 平台,游 ...
- 美团支付宝互探腹地 相爱相杀再度升级
文章原创来自洞见网:http://www.localonline.com.cn/view/ec/735.html,转载请注明出处. 20年前,网络还未盛行,曾有人做过一场行为艺术"不出门, ...
- 无责任猜想#冰桶挑战#大佬们相爱相杀众生相
看#冰桶挑战#大佬们点名的关系图谱,无意中发现很多有趣的关系啊,下面为八妹子自娱自乐无责任猜想,认真你就输了哦! 1. 微软谷歌苹果Facebook,老大哥.新小弟之间的相互厮杀 FACEBOOK的 ...
- Anchor Based和Anchor Free的相爱相杀与ATSS的诞生
前言 我们都知道按照是否出现RPN可将目标检测算法分为two-stage和one-stage,其中one-stage的一个主要代表便是YOLO系列,而根据是否存在先验锚框的定义我们也可以将其分为Anc ...
- 支付宝与微信转战刷脸支付,多年相爱相杀情归何处?
说起阿里巴巴与腾讯,似乎怎么也绕不开马云跟马化腾. 两马同台,自是不同凡响. 有次,两人同台颁奖. 主持人问马云:"你们都信马,你觉得两人之间最显著的区别是什么?" 马云笑答:&q ...
- 30年「相爱相杀」 :30张照片回顾乔布斯和比尔盖茨之间「不得不说」的故事
Python实战社群 Java实战社群 长按识别下方二维码,按需求添加 扫码关注添加客服 进Python社群▲ 扫码关注添加客服 进Java社群▲ 来源丨BI 来源公众号丨新智元(ID:AI_era) ...
最新文章
- 第二届清华大学项目管理精英训练营【敏捷个人】分享
- UVa12604 Caesar Cipher(kmp)
- 联赛前(伪)数据结构专题总结
- php面向对象引用文件,PHP面向对象之对象和引用
- 本文介绍使用OpenCV-Python进行形态学处理
- 没有第三个变量的前提下交换两个变量_很多人连Python变量都没搞懂,说自己会python
- 白话CSS3的新特性
- 第一台微型计算机处理器位数,微处理器芯片的位数指的是什么 - 全文
- Android Studio 文件名颜色代表含义
- h5优秀控件_7个效果震憾的HTML5应用组件
- 各种艺术字、图片在线制作
- Pseudo-3D Residual Networks算法的pytorch代码
- Google File System中文版
- 航拍“中国南北地理分界线” 感受独特景观
- Opengl入门基础-shader着色器画方形并且填颜色
- matlab提取wind底层数据库操作
- java web常用且实用的网站收集
- 浅谈一个完整网站配色方案设计大法2实例篇
- 虐我千百遍之NS3安装
- 也测一个PS3111 / HT9530 / AS2258新玩意儿,做个固态U盘?
热门文章
- GOF设计模式之1:单例设计模式
- .Net学习笔记----2015-06-30(超市收银系统01-仓库类)
- 2008R2Win7管理九DNS冗余和恢复
- [剑指offer][JAVA]面试题第[27]题[二叉树的镜像][递归][栈]
- mysql分布式一致性hash_分布式哈希一致性
- 开机自启动脚本_使用xtu降低笔记本(游戏本)cpu电压及功耗·游戏本延时(以及试着解决开机自启动的问题)...
- Educational Codeforces Round 112 (Rated for Div. 2)(A-D)
- 安卓手机网页 字体垂直方向对齐_初学Excel办公软件字体对齐调整
- qmake生成vs2013工程文件
- 编译pjsip2.1.0 vidgui程序时,xlib保错问题