当前位置: 首页 >数据库 > 第十二节:Lambda、linq、SQL的相爱相杀(1)

第十二节: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) { retu str.Length; }); 

  B. 匿名方法: delegate(string str){retu str.Length;}

  C. lambda语句: (string str)=>{retu str.Length;}

  D. lambda表达式: (string str)=> str.Length

  E.让编译器推断类型: (str)=> str.Length

  F. 去掉不必要的括弧: str=> str.Length

  注意:Lambda语句 和 Lambda表达式 的区别在于,前者在 =>右边有一个语句块(大括号),而后者只有一个表达式(没有retu 和大括号)。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、linq、SQL的相爱相杀(1) _ JavaClub全栈架构师技术笔记

     第十二节:Lambda、linq、SQL的相爱相杀(1) _ JavaClub全栈架构师技术笔记

 表数据:

      第十二节:Lambda、linq、SQL的相爱相杀(1) _ JavaClub全栈架构师技术笔记

     第十二节:Lambda、linq、SQL的相爱相杀(1) _ JavaClub全栈架构师技术笔记

 

 

 

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

第十二节:Lambda、linq、SQL的相爱相杀(1) _ JavaClub全栈架构师技术笔记

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 => new 8 { 9 u.userName,10 u.userAge,11 u.userSex12 }).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 => new20 {21 Name = u.userName,22 Age = u.userAge,23 Sex = u.userSex24 }).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 newUserInfor32 {33 newName = u.userName,34 newAge = u.userAge,35 newSex = u.userSex36 }).ToList();37 sUserList3.ForEach(u =>38 {39 Console.WriteLine("用户名:{0},用户年龄:{1},用户性别:{2}", u.newName, u.newAge, u.newSex);40 });41 }42 #endregion

第十二节:Lambda、linq、SQL的相爱相杀(1) _ JavaClub全栈架构师技术笔记

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

 第十二节:Lambda、linq、SQL的相爱相杀(1) _ JavaClub全栈架构师技术笔记

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) => new 8   { 9UserName = u.userName,10LoginIp = p.loginIp,11LoginCity = p.loginCity,12LoginTime = p.loginTime13 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

 第十二节:Lambda、linq、SQL的相爱相杀(1) _ JavaClub全栈架构师技术笔记

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

 第十二节:Lambda、linq、SQL的相爱相杀(1) _ JavaClub全栈架构师技术笔记

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 retu data.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();5 } 6 #endregion

 第十二节:Lambda、linq、SQL的相爱相杀(1) _ JavaClub全栈架构师技术笔记

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) => new 6 { 7 m.userName, 8 n 9 }).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) _ JavaClub全栈架构师技术笔记

 

 

 

 

 
 
 

!

  • 作       者 : Yaopengfei(姚鹏飞)
  • 博客地址 : http://www.cnblogs.com/yaopengfei/
  • 声     明1 : 如有错误,欢迎讨论,请勿谩骂^_^。
  • 声     明2 : 原创博客请在转载时保留原文链接或在文章开头加上本人博客地址,否则保留追究法律责任的权利。
 

作者:Yaopengfei
来源链接:https://www.cnblogs.com/yaopengfei/p/7269089.html

版权声明:
1、JavaClub(https://www.javaclub.cn)以学习交流为目的,由作者投稿、网友推荐和小编整理收藏优秀的IT技术及相关内容,包括但不限于文字、图片、音频、视频、软件、程序等,其均来自互联网,本站不享有版权,版权归原作者所有。

2、本站提供的内容仅用于个人学习、研究或欣赏,以及其他非商业性或非盈利性用途,但同时应遵守著作权法及其他相关法律的规定,不得侵犯相关权利人及本网站的合法权利。
3、本网站内容原作者如不愿意在本网站刊登内容,请及时通知本站(javaclubcn@163.com),我们将第一时间核实后及时予以删除。





本文链接:https://www.javaclub.cn/database/117638.html

标签:group by
分享给朋友:

“第十二节:Lambda、linq、SQL的相爱相杀(1)” 的相关文章

触发器的定义及优点 2022年05月21日 11:37:15
利用Oracle分析函数row 2022年06月03日 23:42:05
MYSQL查询某字段为空的数据 2022年06月08日 21:35:13
mysql的查询句 2022年06月09日 23:40:52
mysql查询字段为null 返回0 2022年06月10日 20:48:10
shell简单处理mysql查询结果 2022年06月10日 23:22:02
Mysql查询某字段值重复的数据 2022年06月11日 19:39:22