第十三节:Lambda、linq、SQL的相爱相杀(2)
一. Linq开篇
1.Where用法
linq中where的用法与SQL中where的用法基本一致。
#region 01-where用法
{
//1. where用法
//1.1 查询账号为admin的用户信息
Console.WriteLine("---------------------------- 1. where用法 ----------------------------------------");
Console.WriteLine("---------------------------- 1.1 查询账号为admin的用户信息 ----------------------------------------");
List<Sys_UserInfor> sUserList1 = (from u in db.Sys_UserInfor
where u.userAccount == "admin"
select u).ToList(); foreach (var item in sUserList1)
{
Console.WriteLine("用户名:{0},用户账号:{1},用户年龄:{2},用户性别:{3}", item.userName, item.userAccount, item.userAge, item.userSex);
}
//1.2 查询账号为中包含admin且性别为男的用户信息
Console.WriteLine("---------------------------- 1.2 查询账号为中包含admin且性别为男的用户信息 ----------------------------------------");
List<Sys_UserInfor> sUserList2 = (from u in db.Sys_UserInfor
where u.userAccount.Contains("admin") && u.userSex == "男"
select u).ToList();
foreach (var item in sUserList2)
{
Console.WriteLine("用户名:{0},用户账号:{1},用户年龄:{2},用户性别:{3}", item.userName, item.userAccount, item.userAge, item.userSex);
}
}
#endregion

2.Select用法
与前一个章节lambda中介绍的一样,select可以全部查询或查询部分字段
查询部分的时候可以使用匿名类或者实体类,使用匿名的时候也可以指定列名。
#region 02-select用法 (匿名类和非匿名类写法)
{
//2. select用法 (匿名类和非匿名类写法)
//2.1 查询账号中包含 admin 的用户的 姓名、年龄和性别 三条信息 (匿名类的写法,自动生成匿名类名称)
Console.WriteLine("---------------------------- 2. select用法 (匿名类和非匿名类写法) ----------------------------------------");
Console.WriteLine("-------------2.1 查询账号中包含 admin 的用户的 姓名、年龄和性别 三条信息 (匿名类的写法)-------------------------");
var sUserList1 = (from u in db.Sys_UserInfor
where u.userAccount.Contains("admin")
select new
{
u.userName,
u.userAge,
u.userSex
}).ToList();
sUserList1.ForEach(u =>
{
Console.WriteLine("用户名:{0},用户年龄:{1},用户性别:{2}", u.userName, u.userAge, u.userSex);
});
//2.2 查询账号中包含 admin 的用户的 姓名、年龄和性别 三条信息 (匿名类的写法,指定匿名类名称)
Console.WriteLine("---------2.2 查询账号中包含 admin 的用户的 姓名、年龄和性别 三条信息 (匿名类的写法 指定匿名类名称)--------");
var sUserList2 = (from u in db.Sys_UserInfor
where u.userAccount.Contains("admin")
select new
{
Name = u.userName,
Age = u.userAge,
Sex = u.userSex
}).ToList();
sUserList2.ForEach(u =>
{
Console.WriteLine("用户名:{0},用户年龄:{1},用户性别:{2}", u.Name, u.Age, u.Sex);
});
//2.3 查询账号中包含 admin 的用户的 姓名、年龄和性别 三条信息 (非匿名类的写法)
Console.WriteLine("-------------2.3 查询账号中包含 admin 的用户的 姓名、年龄和性别 三条信息 (非匿名类的写法)-------------------------");
List<newUserInfor> sUserList3 = (from u in db.Sys_UserInfor
where u.userAccount.Contains("admin")
select new newUserInfor
{
newName = u.userName,
newAge = u.userAge,
newSex = u.userSex
}).ToList();
sUserList3.ForEach(u =>
{
Console.WriteLine("用户名:{0},用户年龄:{1},用户性别:{2}", u.newName, u.newAge, u.newSex);
});
}
#endregion

3.orderby用法
关键字是:orderby (默认是升序) 和orderby descending
需要按照多个条件进行升序或降序,格式为: orderby x1,x2 descending,x3 (表示先按照x1升序排,x1相同的话,再按照x2降序排,x2相同的话,在按照x3升序排列)
#region 03-orderby用法
{
//区分:在Lambda中有 orderby(OrderByDescending、ThenBy、ThenByDescending),但在Linq中 只有orderby (默认是升序) 和orderby descending
//需要按照多个条件进行升序或降序,格式为: orderby x1,x2 descending,x3 (表示先按照x1升序排,x1相同的话,再按照x2降序排,x2相同的话,在按照x3升序排列)
//3. OrderBy用法 (单条件升降序、多条件综合排序)
//3.1 查询delflag 为1 的所有用户信息,按照时间升序排列
Console.WriteLine("------3. orderby用法 (单条件升降序、多条件综合排序)-------------");
Console.WriteLine("--------------------- 3.1 查询delflag 为1 的所有用户信息,按照时间升序排列 ------------------------------");
List<Sys_UserInfor> sUserList1 = (from u in db.Sys_UserInfor
where u.delFlag ==
orderby u.addTime
select u).ToList();
foreach (var item in sUserList1)
{
Console.WriteLine("用户名:{0},用户账号:{1},用户年龄:{2},用户性别:{3},创建时间:{4}", item.userName, item.userAccount, item.userAge, item.userSex, item.addTime);
}
//3.2 查询delflag 为1 的所有用户信息,先按照时间升序排列,再按照年龄降序
Console.WriteLine("---------------3.2 查询delflag 为1 的所有用户信息,先按照时间升序排列,再按照年龄降序----------------------");
List<Sys_UserInfor> sUserList2 = (from u in db.Sys_UserInfor
where u.delFlag ==
orderby u.addTime, u.userAge descending
select u).ToList();
foreach (var item in sUserList2)
{
Console.WriteLine("用户名:{0},用户账号:{1},用户年龄:{2},用户性别:{3},创建时间:{4}", item.userName, item.userAccount, item.userAge, item.userSex, item.addTime);
}
}
#endregion

4.多表关联查询
用到的用户表和用户登录记录表如下:


这里类比SQL语句里的查询,查询包括内连接和外连接,其中,
1.内连接分为:隐式内连接和显示内连接.特点:二者只是写法不同,查询出来的结果都是多表交叉共有的。
(1).隐式内连接: 多个from并联拼接
(2).显示内连接: join-in-on拼接,注意没有into哦!加上into就成外连接了。
PS:这里的内连接相当于sql中的等值连接inner join。
2.外连接分为:左外连接和右外连接.
(1).左外连接:查询出JOIN左边表的全部数据,JOIN右边的表不匹配的数据用NULL来填充。
(2).右外连接:查询出JOIN右边表的全部数据,JOIN左边的表不匹配的数据用NULL来填充。
PS:linq中没有sql中的left/right join, 只有join,左外连接和右外连接通过颠倒数据的顺序来实现。
注:外连接join后必须有into,然后可以加上XX.DefaultIfEmpty(),表示对于引用类型将返回null,而对于值类型则返回0。对于结构体类型,则会根据其成员类型将它们相应地初始化为null(引用类型)或0(值类型)
3. 分析几个场景,一对一,一对多,而且还要统计个数的案例
(1).用户表-用户详情表(一对一):用内连接
(2).用户表-用户登录记录表(一对零,一对多):用左外连接,用户表为左,如果统计个数需要用Distinct()去重.
//4.查询账号中含有admin的所有用户的用户昵称、账号、和登录信息
//4.1 隐式内连接(匿名类且不指定名称)
Console.WriteLine("---------------04-多表关联查询--------------------");
Console.WriteLine("---------------4.1 隐式内连接(匿名类且不指定名称)--------------------");
var uList1 = (from a in db.Sys_UserInfor
from b in db.LoginRecords
where a.id == b.userId
select new
{
a.userName,
a.userAccount,
b.loginCity,
b.loginIp,
b.loginTime
}).ToList();
foreach (var item in uList1)
{
Console.WriteLine("姓名:{0},账号:{1},登录城市:{2},登录IP:{3},登录时间:{4}", item.userName, item.userAccount, item.loginCity, item.loginIp, item.loginTime);
}
//4.2 显式内链接(匿名类 且部分列指定名称)
Console.WriteLine("---------------4.2 显式内链接(匿名类 且部分列指定名称) --------------------");
var uList2 = (from a in db.Sys_UserInfor
join b in db.LoginRecords on a.id equals b.userId
select new
{
UserName = a.userName,
UserAccount = a.userAccount,
b.loginCity,
b.loginIp,
b.loginTime
}).ToList();
foreach (var item in uList2)
{
Console.WriteLine("姓名:{0},账号:{1},登录城市:{2},登录IP:{3},登录时间:{4}", item.UserName, item.UserAccount, item.loginCity, item.loginIp, item.loginTime);
}
//4.3 查询所有用户的登录信息(左外连接的方式)
//join时必须将join后的表into到一个新的变量XX中,然后要用XX.DefaultIfEmpty()表示外连接。
//DefaultIfEmpty使用了泛型中的default关键字。default关键字对于引用类型将返回null,而对于值类型则返回0。对于结构体类型,则会根据其成员类型将它们相应地初始化为null(引用类型)或0(值类型)
Console.WriteLine("-----------------------4.3 查询所有用户的登录信息(左外连接的方式)----------------------------");
var uList3 = (from a in db.Sys_UserInfor
join b in db.LoginRecords on a.id equals b.userId into fk
from c in fk.DefaultIfEmpty()
select new
{
UserName = a.userName,
UserAccount = a.userAccount,
c.loginCity,
c.loginIp,
c.loginTime
}).ToList();
foreach (var item in uList3)
{
Console.WriteLine("姓名:{0},账号:{1},登录城市:{2},登录IP:{3},登录时间:{4}", item.UserName, item.UserAccount, item.loginCity, item.loginIp, item.loginTime);
}
// 4.4 查询所有用户的登录信息(右外连接的方式)
Console.WriteLine("-----------------------4.4 查询所有用户的登录信息(右外连接的方式)----------------------------");
var uList4 = (from a in db.LoginRecords
join b in db.Sys_UserInfor on a.userId equals b.id into fk
from c in fk.DefaultIfEmpty()
select new
{
UserName = c.userName,
UserAccount = c.userAccount,
a.loginCity,
a.loginIp,
a.loginTime
}).ToList();
foreach (var item in uList4)
{
Console.WriteLine("姓名:{0},账号:{1},登录城市:{2},登录IP:{3},登录时间:{4}", item.UserName, item.UserAccount, item.loginCity, item.loginIp, item.loginTime);
}
//4.5 查询每个用户的登录次数(用且应该用左外连接 )
//注:这里需要加一个Distinct()去重,否则同一个账号会查出来多条数据重复了
Console.WriteLine("-----------------------4.5 查询每个用户的登录次数(用且应该用左外连接 )----------------------------");
var uList5 = (from a in db.Sys_UserInfor
join b in db.LoginRecords on a.id equals b.userId into fk
select new
{
UserName = a.userName,
UserAccount = a.userAccount,
loginCount = fk.Count()
}).Distinct().ToList();
foreach (var item in uList5)
{
Console.WriteLine($"姓名:{item.UserName},账号:{item.UserAccount},登录次数:{item.loginCount}");
}
运行 结果:

5. group by into 分组
#region 05-group By分组(匿名类写法)
{
//5. GroupBy分组(需要重点看一下)
//5.1 根据用户的性别进行分类,然后将不同性别的用户信息输出来
Console.WriteLine("-------------------- 5. GroupBy分组------------------------");
Console.WriteLine("-------------------- 5.1 根据用户的性别进行分类,然后将不同性别的用户信息输出来------------------------");
var sUserListGroup = (from u in db.Sys_UserInfor
group u by u.userSex into fk
select fk).ToList();
foreach (var group in sUserListGroup)
{
Console.WriteLine("性别为:{0}", group.Key); //分组依据的字段内容
foreach (var item in group)
{
Console.WriteLine("用户名:{0},用户账号:{1},用户年龄:{2},用户性别:{3}", item.userName, item.userAccount, item.userAge, item.userSex);
}
}
//5.2 根据用户性别进行分类,然后将不同性别的年龄大于等于21岁的用户信息输出来
Console.WriteLine("-------------5.2 根据用户性别进行分类,然后将不同性别的年龄大于等于21岁的用户信息输出来-------------------");
var sUserListGroup2 = (from u in db.Sys_UserInfor
where u.userAge >=
group u by u.userSex into fk
select fk).ToList();
foreach (var group in sUserListGroup2)
{
Console.WriteLine("性别为:{0}", group.Key); //分组依据的字段内容
foreach (var item in group)
{
Console.WriteLine("用户名:{0},用户账号:{1},用户年龄:{2},用户性别:{3}", item.userName, item.userAccount, item.userAge, item.userSex);
}
}
}
#endregion

6. skip和take用法
#region 06-Skip和Take用法
{ //6. Skip和Take 分页用法
//skip表示跳过多少条,Take表示取多少条
//6.1 根据时间降序排列,取第2和第3条数据(即先排序,然后跨过1条,取2条数据)
Console.WriteLine("--------------------6. Skip和Take 分页用法------------------------");
Console.WriteLine("---------6.1 根据时间降序排列,取用户信息中的第2和第3条数据(即先排序,然后跨过1条,取2条数据)---------");
var sUserList = (from u in db.Sys_UserInfor
orderby u.addTime descending
select u).Skip().Take().ToList();
sUserList.ForEach(u =>
{
Console.WriteLine("用户名:{0},用户年龄:{1},用户性别:{2},创建时间:{3}", u.userName, u.userAge, u.userSex, u.addTime);
});
}
#endregion

第十三节:Lambda、linq、SQL的相爱相杀(2)的更多相关文章
- 第十四节:Lambda、linq、SQL的相爱相杀(3)
一. SQL 开篇 1. where用法 #region 封装EF调用SQL语句查询 public static List<T> ExecuteQuery<T>(string ...
- 第十二节:Lambda、linq、SQL的相爱相杀(1)
一. 谈情怀 Lambda.Linq.SQL伴随着我的开发一年又一年,但它们三者并没有此消彼长,各自占有这一定的比重,起着不可替代的作用. 相信我们最先接触的应该就是SQL了,凡是科班出身的人,大学 ...
- 阿里云CDN技术掌舵人文景:相爱相杀一路狂奔的这十年
导读:提到阿里云CDN,不得不提技术掌舵人姚伟斌(文景),虽然他不是团队中最“老”的同学,但他却历经了淘宝业务发展最为飞速的几年,见证了从最初服务淘宝和集团内部的CDN,到如今国内服务客户最多的云CD ...
- 猎豹CEO傅盛:与周鸿祎、雷军、马化腾、马云的的相爱相杀
百度百科:傅盛,男,1978年3月6日出生在江西景德镇,毕业于山东工商学院信息管理与信息系统专业. 2003年加入3721公司.2005年加入奇虎360,带领团队打造了安全类软件360安全卫士.200 ...
- rem与px的相爱相杀
rem 简介:为元素设定字体大小:相对大小:只相对HTML根元素. 优点:只修改根元素就可以成比例调整所有字体的大小. bug:IE8及更早版本不兼容. hack:多写一个绝对单位px的声明,不兼容版 ...
- 我与UML相爱相杀的狗血日常
前言 该怎么说呢,在专业母亲的包办婚姻和我不得不为日后的百万家产[日后的百万年薪,我怕是在做梦]下,我和UML的婚后生活正式开始了.第一天回娘家我亓老师就给出了她最爱的编程作业.说实话,我当初以头发为 ...
- GoPath模式和GoMoudle模式的相爱相杀
相信看我文章的文章的童鞋,golang版本已经是1.3版本以上.如果你的版本还停留在1.3以下,那这篇文章可以做为你的提升之法. go moudle的前世今生 前世-gopath gopath是什么 ...
- React关于constructor与super(props)之间的相爱相杀
我们先把菜鸟教程的一段代码拿过来分析一下.下面这段代码是用了将生命周期方法添加到类中实现时钟效果. // 将生命周期方法添加到类中 class Clock extends React.Componen ...
- FreeSql (二十四)Linq To Sql 语法使用介绍
原本不支持 IQueryable 主要出于使用习惯的考虑,如果继承 IQueryable,编写代码的智能总会提示出现一堆你不想使用的方法(对不起,我有强迫症),IQueryable 自身提供了一堆没法 ...
随机推荐
- 6.1Python数据处理篇之pandas学习系列(一)认识pandas
目录 目录 (一)介绍与测试 2.作用: 3.导入的格式 4.小测试 (二)数据类型 1.两种重要的数据类型 2.pandas与numpy的比较 目录 (一)介绍与测试 号称处理数据与分析数据最好的第 ...
- SpringBoot使用注解实现事务管理
conttoller controller和普通的controller类一样, 不用改变 @RequestMapping(value = "/path/{id}", method ...
- 既然CPU同一时间只能执行一个线程,为什么存在并发问题
一点小疑惑终于解开啦 1.CPU的时间是按时间片分的,而不是一个时间点,并发问题是由于CPU线程切换导致的. 现在假设有一段代码 if(i == 1) { i++; //断点1 system.out. ...
- vue 快速入门、常用指令(1)
1. vue.js的快速入门使用 1.1 vue.js库的下载 vue.js是目前前端web开发最流行的工具库之一,由尤雨溪在2014年2月发布的. 官方网站 中文:https://cn.vuejs. ...
- 苹果绿RGB值
ESL的值为:85,123,205 RGB的值为:199,237,204 ESL和RGB只需填一个即可,另一个会自动调整~
- 在Bootstrap开发框架的前端视图中使用@RenderPage实现页面内容模块化的隔离,减少复杂度
在很多开发的场景中,很多情况下我们需要考虑抽象.以及模块化等方面的内容,其目的就是为了使得开发的时候关注的变化内容更加少一些,整体开发更加简单化,从而减少开发的复杂度,在Winform开发的时候,往往 ...
- golang lua使用示例
package main import ( "fmt" "github.com/yuin/gopher-lua" ) func hello(L *lua.LSt ...
- 关于表单元素的name及HTML中的id
这种在上高级WEB课时,老师为表单元素赋了name值,之后直接在JS中使用该值而不需要使用document.get...来获取了,例: <!DOCTYPE html> <html&g ...
- 周末学习笔记——day01(函数,函数对象,嵌套调用,名称空间,作用域,闭包,装饰器)
一,复习 字符编码 文件头:py2—ASCII,py3—UTF-8 三种字符串:u' ' b ' ' r ' ' u' ' .endcode(' utf-8 ') b' '.deconde(' utf ...
- XSS原理及防范
Xss(cross-site scripting)攻击指的是攻击者往Web页面里插入恶意html标签或者javascript代码.比如:攻击者在论坛中放一个看似安全的链接,骗取用户点击后,窃取cook ...