第十三节:Lambda、linq、SQL的相爱相杀(2)

一. Linq开篇

1.Where用法

 linq中where的用法与SQL中where的用法基本一致。

 1             #region 01-where用法
 2             {
 3                 //1. where用法
 4                 //1.1 查询账号为admin的用户信息
 5                 Console.WriteLine("---------------------------- 1. where用法   ----------------------------------------");
 6                 Console.WriteLine("---------------------------- 1.1 查询账号为admin的用户信息   ----------------------------------------");
 7                 List<Sys_UserInfor> sUserList1 = (from u in db.Sys_UserInfor
 8                                                   where u.userAccount == "admin"
 9                                                   select u).ToList();
10 
11                 foreach (var item in sUserList1)
12                 {
13                     Console.WriteLine("用户名:{0},用户账号:{1},用户年龄:{2},用户性别:{3}", item.userName, item.userAccount, item.userAge, item.userSex);
14                 }
15                 //1.2  查询账号为中包含admin且性别为男的用户信息
16                 Console.WriteLine("---------------------------- 1.2  查询账号为中包含admin且性别为男的用户信息   ----------------------------------------");
17                 List<Sys_UserInfor> sUserList2 = (from u in db.Sys_UserInfor
18                                                   where u.userAccount.Contains("admin") && u.userSex == ""
19                                                   select u).ToList();
20                 foreach (var item in sUserList2)
21                 {
22                     Console.WriteLine("用户名:{0},用户账号:{1},用户年龄:{2},用户性别:{3}", item.userName, item.userAccount, item.userAge, item.userSex);
23                 }
24             }
25             #endregion        

2.Select用法

 与前一个章节lambda中介绍的一样,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 = (from u in db.Sys_UserInfor
 8                                   where u.userAccount.Contains("admin")
 9                                   select new
10                                   {
11                                       u.userName,
12                                       u.userAge,
13                                       u.userSex
14                                   }).ToList();
15                 sUserList1.ForEach(u =>
16                 {
17                     Console.WriteLine("用户名:{0},用户年龄:{1},用户性别:{2}", u.userName, u.userAge, u.userSex);
18                 });
19                 //2.2 查询账号中包含 admin 的用户的 姓名、年龄和性别 三条信息 (匿名类的写法,指定匿名类名称)
20                 Console.WriteLine("---------2.2 查询账号中包含 admin 的用户的 姓名、年龄和性别 三条信息 (匿名类的写法 指定匿名类名称)--------");
21                 var sUserList2 = (from u in db.Sys_UserInfor
22                                   where u.userAccount.Contains("admin")
23                                   select new
24                                   {
25                                       Name = u.userName,
26                                       Age = u.userAge,
27                                       Sex = u.userSex
28                                   }).ToList();
29                 sUserList2.ForEach(u =>
30                 {
31                     Console.WriteLine("用户名:{0},用户年龄:{1},用户性别:{2}", u.Name, u.Age, u.Sex);
32                 });
33                 //2.3 查询账号中包含 admin 的用户的 姓名、年龄和性别 三条信息 (非匿名类的写法)
34                 Console.WriteLine("-------------2.3 查询账号中包含 admin 的用户的 姓名、年龄和性别 三条信息 (非匿名类的写法)-------------------------");
35                 List<newUserInfor> sUserList3 = (from u in db.Sys_UserInfor
36                                                  where u.userAccount.Contains("admin")
37                                                  select new newUserInfor
38                                                  {
39                                                      newName = u.userName,
40                                                      newAge = u.userAge,
41                                                      newSex = u.userSex
42                                                  }).ToList();
43                 sUserList3.ForEach(u =>
44                 {
45                     Console.WriteLine("用户名:{0},用户年龄:{1},用户性别:{2}", u.newName, u.newAge, u.newSex);
46                 });
47             }
48             #endregion

3.orderby用法

 关键字是:orderby (默认是升序) 和orderby descending

需要按照多个条件进行升序或降序,格式为:  orderby x1,x2 descending,x3 (表示先按照x1升序排,x1相同的话,再按照x2降序排,x2相同的话,在按照x3升序排列)
 1             #region 03-orderby用法
 2             {
 3                 //区分:在Lambda中有 orderby(OrderByDescending、ThenBy、ThenByDescending),但在Linq中 只有orderby (默认是升序) 和orderby descending
 4                 //需要按照多个条件进行升序或降序,格式为:  orderby x1,x2 descending,x3 (表示先按照x1升序排,x1相同的话,再按照x2降序排,x2相同的话,在按照x3升序排列)
 5                 //3. OrderBy用法 (单条件升降序、多条件综合排序)
 6                 //3.1 查询delflag 为1 的所有用户信息,按照时间升序排列
 7                 Console.WriteLine("------3. orderby用法  (单条件升降序、多条件综合排序)-------------");
 8                 Console.WriteLine("--------------------- 3.1 查询delflag 为1 的所有用户信息,按照时间升序排列   ------------------------------");
 9                 List<Sys_UserInfor> sUserList1 = (from u in db.Sys_UserInfor
10                                                   where u.delFlag == 1
11                                                   orderby u.addTime
12                                                   select u).ToList();
13                 foreach (var item in sUserList1)
14                 {
15                     Console.WriteLine("用户名:{0},用户账号:{1},用户年龄:{2},用户性别:{3},创建时间:{4}", item.userName, item.userAccount, item.userAge, item.userSex, item.addTime);
16                 }
17                 //3.2 查询delflag 为1 的所有用户信息,先按照时间升序排列,再按照年龄降序
18                 Console.WriteLine("---------------3.2 查询delflag 为1 的所有用户信息,先按照时间升序排列,再按照年龄降序----------------------");
19                 List<Sys_UserInfor> sUserList2 = (from u in db.Sys_UserInfor
20                                                   where u.delFlag == 1
21                                                   orderby u.addTime, u.userAge descending
22                                                   select u).ToList();
23                 foreach (var item in sUserList2)
24                 {
25                     Console.WriteLine("用户名:{0},用户账号:{1},用户年龄:{2},用户性别:{3},创建时间:{4}", item.userName, item.userAccount, item.userAge, item.userSex, item.addTime);
26                 }
27             }
28             #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()去重.

 1                 //4.查询账号中含有admin的所有用户的用户昵称、账号、和登录信息
 2                 //4.1 隐式内连接(匿名类且不指定名称)
 3                 Console.WriteLine("---------------04-多表关联查询--------------------");
 4                 Console.WriteLine("---------------4.1 隐式内连接(匿名类且不指定名称)--------------------");
 5                 var uList1 = (from a in db.Sys_UserInfor
 6                               from b in db.LoginRecords
 7                               where a.id == b.userId 
 8                               select new
 9                               {
10                                   a.userName,
11                                   a.userAccount,
12                                   b.loginCity,
13                                   b.loginIp,
14                                   b.loginTime
15                               }).ToList();
16                 foreach (var item in uList1)
17                 {
18                     Console.WriteLine("姓名:{0},账号:{1},登录城市:{2},登录IP:{3},登录时间:{4}", item.userName, item.userAccount, item.loginCity, item.loginIp, item.loginTime);
19                 }
20                 //4.2 显式内链接(匿名类 且部分列指定名称)  
21                 Console.WriteLine("---------------4.2 显式内链接(匿名类 且部分列指定名称)  --------------------");
22                 var uList2 = (from a in db.Sys_UserInfor
23                               join b in db.LoginRecords on a.id equals b.userId                         
24                               select new
25                               {
26                                   UserName = a.userName,
27                                   UserAccount = a.userAccount,
28                                   b.loginCity,
29                                   b.loginIp,
30                                   b.loginTime
31                               }).ToList();
32                 foreach (var item in uList2)
33                 {
34                     Console.WriteLine("姓名:{0},账号:{1},登录城市:{2},登录IP:{3},登录时间:{4}", item.UserName, item.UserAccount, item.loginCity, item.loginIp, item.loginTime);
35                 }
36                 //4.3 查询所有用户的登录信息(左外连接的方式)
37                 //join时必须将join后的表into到一个新的变量XX中,然后要用XX.DefaultIfEmpty()表示外连接。
38                 //DefaultIfEmpty使用了泛型中的default关键字。default关键字对于引用类型将返回null,而对于值类型则返回0。对于结构体类型,则会根据其成员类型将它们相应地初始化为null(引用类型)或0(值类型)
39                 Console.WriteLine("-----------------------4.3 查询所有用户的登录信息(左外连接的方式)----------------------------");
40                 var uList3 = (from a in db.Sys_UserInfor
41                               join b in db.LoginRecords on a.id equals b.userId into fk
42                               from c in fk.DefaultIfEmpty()
43                               select new
44                               {
45                                   UserName = a.userName,
46                                   UserAccount = a.userAccount,
47                                   c.loginCity,
48                                   c.loginIp,
49                                   c.loginTime
50                               }).ToList();
51                 foreach (var item in uList3)
52                 {
53                     Console.WriteLine("姓名:{0},账号:{1},登录城市:{2},登录IP:{3},登录时间:{4}", item.UserName, item.UserAccount, item.loginCity, item.loginIp, item.loginTime);
54                 }
55                 // 4.4 查询所有用户的登录信息(右外连接的方式)
56                 Console.WriteLine("-----------------------4.4 查询所有用户的登录信息(右外连接的方式)----------------------------");
57                 var uList4 = (from a in db.LoginRecords
58                               join b in db.Sys_UserInfor on a.userId equals b.id into fk
59                               from c in fk.DefaultIfEmpty()
60                               select new
61                               {
62                                   UserName = c.userName,
63                                   UserAccount = c.userAccount,
64                                   a.loginCity,
65                                   a.loginIp,
66                                   a.loginTime
67                               }).ToList();
68                 foreach (var item in uList4)
69                 {
70                     Console.WriteLine("姓名:{0},账号:{1},登录城市:{2},登录IP:{3},登录时间:{4}", item.UserName, item.UserAccount, item.loginCity, item.loginIp, item.loginTime);
71                 }
72                 //4.5 查询每个用户的登录次数(用且应该用左外连接 )
73                 //注:这里需要加一个Distinct()去重,否则同一个账号会查出来多条数据重复了
74                 Console.WriteLine("-----------------------4.5 查询每个用户的登录次数(用且应该用左外连接 )----------------------------");
75                 var uList5 = (from a in db.Sys_UserInfor
76                               join b in db.LoginRecords on a.id equals b.userId into fk
77                               select new
78                               {
79                                   UserName = a.userName,
80                                   UserAccount = a.userAccount,
81                                   loginCount = fk.Count()
82                               }).Distinct().ToList();
83                 foreach (var item in uList5)
84                 {
85                     Console.WriteLine($"姓名:{item.UserName},账号:{item.UserAccount},登录次数:{item.loginCount}");
86                 }

 运行 结果:

 5. group by into 分组

 1   #region 05-group By分组(匿名类写法)
 2             {
 3                 //5. GroupBy分组(需要重点看一下)
 4                 //5.1 根据用户的性别进行分类,然后将不同性别的用户信息输出来
 5                 Console.WriteLine("-------------------- 5. GroupBy分组------------------------");
 6                 Console.WriteLine("-------------------- 5.1 根据用户的性别进行分类,然后将不同性别的用户信息输出来------------------------");
 7                 var sUserListGroup = (from u in db.Sys_UserInfor
 8                                       group u by u.userSex into fk
 9                                       select fk).ToList();      
10                 foreach (var group in sUserListGroup)
11                 {
12                     Console.WriteLine("性别为:{0}", group.Key);    //分组依据的字段内容
13                     foreach (var item in group)
14                     {
15                         Console.WriteLine("用户名:{0},用户账号:{1},用户年龄:{2},用户性别:{3}", item.userName, item.userAccount, item.userAge, item.userSex);
16                     }
17                 }
18                 //5.2 根据用户性别进行分类,然后将不同性别的年龄大于等于21岁的用户信息输出来
19                 Console.WriteLine("-------------5.2 根据用户性别进行分类,然后将不同性别的年龄大于等于21岁的用户信息输出来-------------------");
20                 var sUserListGroup2 = (from u in db.Sys_UserInfor
21                                        where u.userAge >= 21
22                                       group u by u.userSex into fk
23                                       select fk).ToList();  
24                 foreach (var group in sUserListGroup2)
25                 {
26                     Console.WriteLine("性别为:{0}", group.Key);    //分组依据的字段内容
27                     foreach (var item in group)
28                     {
29                         Console.WriteLine("用户名:{0},用户账号:{1},用户年龄:{2},用户性别:{3}", item.userName, item.userAccount, item.userAge, item.userSex);
30                     }
31                 }
32             }
33             #endregion

 

6. skip和take用法

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

 

 

!

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

 

posted @ 2017-08-07 22:19  Yaopengfei  阅读(1527)  评论(3编辑  收藏