一. 談情懷html
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語句 。spa
補充Lambad的發展歷史: 3d
A. 內置委託: new Func<string, int>(delegate(string str) { return str.Length; }); code
B. 匿名方法: delegate(string str){return str.Length;}htm
C. lambda語句: (string str)=>{return str.Length;}blog
D. lambda表達式: (string str)=> str.Length
E.讓編譯器推斷類型: (str)=> str.Length
F. 去掉沒必要要的括弧: str=> str.Length
注意:Lambda語句 和 Lambda表達式 的區別在於,前者在 =>右邊有一個語句塊(大括號),然後者只有一個表達式(沒有return 和大括號)。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結尾。
表結構:
表數據:
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
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.userSex 12 }).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 => new 20 { 21 Name = u.userName, 22 Age = u.userAge, 23 Sex = u.userSex 24 }).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 newUserInfor 32 { 33 newName = u.userName, 34 newAge = u.userAge, 35 newSex = u.userSex 36 }).ToList(); 37 sUserList3.ForEach(u => 38 { 39 Console.WriteLine("用戶名:{0},用戶年齡:{1},用戶性別:{2}", u.newName, u.newAge, u.newSex); 40 }); 41 } 42 #endregion
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
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 { 9 UserName = u.userName, 10 LoginIp = p.loginIp, 11 LoginCity = p.loginCity, 12 LoginTime = p.loginTime 13 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
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
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 return data.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList(); 5 } 6 #endregion
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