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