第十三節: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        

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM