目錄
簡單介紹
比較實作
简单介绍
对比实现
首頁 後端開發 C#.Net教程 SQL、LINQ和Lambda表達式

SQL、LINQ和Lambda表達式

Feb 23, 2017 am 10:05 AM
lambda


首先說說這三者完全是三種不同的東西,SQL是結構化查詢語言(Structured Query Language)簡稱,這大家再熟悉不過了,以下主要介紹LINQ和Lambda表達式的基本概念以及同一查詢這三者的不同實作。

簡單介紹

LINQ(Language Integrate Query)是語言整合查詢他在物件和資料之間建立一種對應的關係,可以使用存取記憶體物件的方式查詢資料集合。 LINQ查詢是C#中的一種語言建構。因此開發人員可以再C#程式碼來總結巢狀類似SQL語句的查詢表達式,進而實現資料查詢的功能。 LINQ也不是簡單地作為C#中嵌套查詢表達式,而是將查詢表達式作為C#的一種語法。
 在.NET類別庫中,LINQ相關類別庫都在System.Linq命名空間下,該命名空間提供支援使用LINQ進行查詢的類別和接口,其中最主要的是以下兩個類別和兩個介面。
 ※IEnumerable介面:它表示可以查詢的資料集合,一個查詢通常是逐一對集合中的元素進行篩選操作,傳回一個新的IEnumerable接口,用來保存查詢結果。
 ※IQueryable介面:他繼承IEnumerable接口,表示一個可以查詢的表達式目錄樹。
 ※Enumerable類別:它透過對IEnumerable提供擴充方法,實現LINQ標準查詢運算子。包括過路、導航、排序、查詢、聯結、求和、求最大值、求最小值等操作。
 ※Queryable類別:它透過對IQueryable提供擴充方法,實作LINQ標準查詢運算子。包括過路、導航、排序、查詢、聯結、求和、求最大值、求最小值等操作。
 Lambda表達式其實是一個匿名函數,它可以說是對LINQ的補充。由於LINQ查詢關鍵字和IEnumerable介面的方法之間有一個對應關係,但LINQ查詢運算式中可以使用的查詢功能很少。在實際開發中透過查詢結果或資料來源進行方法調用,從而進行更多的查詢操作。由於Lambda表達式是匿名函數,它可以賦值到一個委託,而在IEnumerable介面的方法中很多透過函數委託來實現自訂運算、條件等操作,所以Lambda表達式在LINQ中被廣泛使用。

比較實作

※查詢全部內容

1 查询Student表的所有记录。
2 select * from student
3 Linq:
4     from s in Students
5     select s
6 Lambda:
7     Students.Select( s => s)
登入後複製
登入後複製

※按列查詢

select sname,ssex,class from student 
3 Linq: 
4     from s in Students 
5     select new { 
6         s.SNAME, 
7         s.SSEX, 
8         s.CLASS
 9     }
 10 Lambda:
 11     Students.Select( s => new {
 12         SNAME = s.SNAME,SSEX = s.SSEX,CLASS = s.CLASS
 13     })
登入後複製
登入後複製

※distinct去重查詢

 查询教师所有的单位即不重复的Depart列。
2 select distinct depart from teacher
3 Linq:
4     from t in Teachers.Distinct()
5     select t.DEPART6 Lambda:
7     Teachers.Distinct().Select( t => t.DEPART)
登入後複製

※兩個區間內查詢

1 查询Score表中成绩在60到80之间的所有记录。
 2 select * from score where degree between 60 and 80
 3 Linq: 
 4     from s in Scores 
 5     where s.DEGREE >= 60 && s.DEGREE < 80
 6     select s 
 7 Lambda: 
 8     Scores.Where( 
 9         s => (
 10                 s.DEGREE >= 60 && s.DEGREE < 80
 11              )
 12     )
登入後複製
登入後複製

※在一個範圍內查詢

 select * from score where degree in (85,86,88)
 2 Linq:
 3     from s in Scores
 4     where (
 5             new decimal[]{85,86,88}
 6           ).Contains(s.DEGREE)
 7     select s
 8 Lambda:
 9     Scores.Where( s => new Decimal[] {85,86,88}.Contains(s.DEGREE))
登入後複製
登入後複製

※或關係查詢

 查询Student表中"95031"班或性别为"女"的同学记录。
 2 select * from student where class =&#39;95031&#39; or ssex= N&#39;女&#39;
 3 Linq:
 4     from s in Students
 5     where s.CLASS == "95031"
 6        || s.CLASS == "女"
 7     select s
 8 Lambda:
 9     Students.Where(s => ( s.CLASS == "95031" || s.CLASS == "女"))
登入後複製
登入後複製

※排序

 以Class降序查询Student表的所有记录。
 2 select * from student order by Class DESC
 3 Linq:
 4     from s in Students
 5     orderby s.CLASS descending
 6     select s
 7 Lambda:
 8     Students.OrderByDescending(s => s.CLASS)
登入後複製
登入後複製

※行數查詢

 select count(*) from student where class = &#39;95031&#39;
 2 Linq: 
 3     (    from s in Students 
 4         where s.CLASS == "95031"
 5         select s 
 6     ).Count() 
 7 Lambda: 
 8     Students.Where( s => s.CLASS == "95031" ) 
 9                 .Select( s => s)
 10                     .Count()
登入後複製
登入後複製

※平均值查詢

 查询&#39;3-105&#39;号课程的平均分。
 2 select avg(degree) from score where cno = &#39;3-105&#39;
 3 Linq: 
 4     ( 
 5         from s in Scores 
 6         where s.CNO == "3-105"
 7         select s.DEGREE 
 8     ).Average() 
 9 Lambda:
 10     Scores.Where( s => s.CNO == "3-105")
 11             .Select( s => s.DEGREE)
登入後複製
登入後複製

※潛逃查詢

查询Score表中的最高分的学生学号和课程号。
 2 select distinct s.Sno,c.Cno from student as s,course as c ,score as sc 
 3 where s.sno=(select sno from score where degree = (select max(degree) from score)) 
 4 and c.cno = (select cno from score where degree = (select max(degree) from score)) 
 5 Linq: 
 6     ( 
 7         from s in Students 
 8         from c in Courses 
 9         from sc in Scores
 10         let maxDegree = (from sss in Scores
 11                         select sss.DEGREE
 12                         ).Max()
 13         let sno = (from ss in Scores
 14                 where ss.DEGREE == maxDegree
 15                 select ss.SNO).Single().ToString()
 16         let cno = (from ssss in Scores
 17                 where ssss.DEGREE == maxDegree
 18                 select ssss.CNO).Single().ToString()
 19         where s.SNO == sno && c.CNO == cno
 20         select new {
 21             s.SNO,
 22             c.CNO
 23         }
 24     ).Distinct()
登入後複製

※分組

 查询Score表中至少有5名学生选修的并以3开头的课程的平均分数。
 2 select avg(degree) from score where cno like &#39;3%&#39; group by Cno having count(*)>=5
 3 Linq: 
 4         from s in Scores 
 5         where s.CNO.StartsWith("3") 
 6         group s by s.CNO 
 7         into cc 
 8         where cc.Count() >= 5
 9         select cc.Average( c => c.DEGREE)
 10 Lambda:
 11     Scores.Where( s => s.CNO.StartsWith("3") )
 12             .GroupBy( s => s.CNO )
 13               .Where( cc => ( cc.Count() >= 5) )
 14                 .Select( cc => cc.Average( c => c.DEGREE) )
 15 Linq: SqlMethod
 16 like也可以这样写:
 17     s.CNO.StartsWith("3") or SqlMethods.Like(s.CNO,"%3")
登入後複製
登入後複製

※分組過濾

查询Score表中至少有5名学生选修的并以3开头的课程的平均分数。
 2 select avg(degree) from score where cno like &#39;3%&#39; group by Cno having count(*)>=5
 3 Linq: 
 4         from s in Scores 
 5         where s.CNO.StartsWith("3") 
 6         group s by s.CNO 
 7         into cc 
 8         where cc.Count() >= 5
 9         select cc.Average( c => c.DEGREE)
 10 Lambda:
 11     Scores.Where( s => s.CNO.StartsWith("3") )
 12             .GroupBy( s => s.CNO )
 13               .Where( cc => ( cc.Count() >= 5) )
 14                 .Select( cc => cc.Average( c => c.DEGREE) )
 15 Linq: SqlMethod
 16 like也可以这样写:
 17     s.CNO.StartsWith("3") or SqlMethods.Like(s.CNO,"%3")
登入後複製
登入後複製

※多表聯合查詢

 select sc.sno,c.cname,sc.degree from course as c,score as sc where c.cno = sc.cno
 2 Linq: 
 3     from c in Courses 
 4     join sc in Scores 
 5     on c.CNO equals sc.CNO
 6     select new 
 7     { 
 8         sc.SNO,c.CNAME,sc.DEGREE
 9     }
 10 Lambda:
 11     Courses.Join ( Scores, c => c.CNO,
 12                              sc => sc.CNO,
 13                              (c, sc) => new
 14                                         {
 15                                             SNO = sc.SNO,
 16                                             CNAME = c.CNAME,
 17                                             DEGREE = sc.DEGREE
 18                                         })
 19                 .Average()
登入後複製
登入後複製

以上內容是本人查閱資料做的一些整理和總結,有不足之處請大家批評指正!

首先說這三者完全是三種不同的東西,SQL是結構化查詢語言(Structured Query Language)簡稱,這大家再熟悉不過了,以下主要介紹LINQ和Lambda表達式的基本概念以及同一查詢這三者的不同實現。

简单介绍

LINQ(Language Integrate Query)是语言集成查询他在对象和数据之间建立一种对应的关系,可以使用访问内存对象的方式查询数据集合。LINQ查询是C#中的一种语言构造。因此开发人员可以再C#代码汇总嵌套类似于SQL语句的查询表达式,从而实现数据查询的功能。LINQ也不是简单地作为C#中嵌套查询表达式,而是将查询表达式作为C#的一种语法。
在.NET类库中,LINQ相关类库都在System.Linq命名空间下,该命名空间提供支持使用LINQ进行查询的类和接口,其中最主要的是以下两个类和两个接口。
※IEnumerable接口:它表示可以查询的数据集合,一个查询通常是逐个对集合中的元素进行筛选操作,返回一个新的IEnumerable接口,用来保存查询结果。
※IQueryable接口:他继承IEnumerable接口,表示一个可以查询的表达式目录树。
※Enumerable类:它通过对IEnumerable提供扩展方法,实现LINQ标准查询运算符。包括过路、导航、排序、查询、联接、求和、求最大值、求最小值等操作。
※Queryable类:它通过对IQueryable提供扩展方法,实现LINQ标准查询运算符。包括过路、导航、排序、查询、联接、求和、求最大值、求最小值等操作。
Lambda表达式实际上是一个匿名函数,它可以说是对LINQ的补充。由于LINQ查询关键字和IEnumerable接口的方法之间有一个对应关系,但是LINQ查询表达式中可以使用的查询功能很少。在实际开发中通过查询结果或数据源进行方法调用,从而进行更多的查询操作。由于Lambda表达式是匿名函数,它可以赋值到一个委托,而在IEnumerable接口的方法中很多通过函数委托来实现自定义运算、条件等操作,所以Lambda表达式在LINQ中被广泛使用。

对比实现

※查询全部内容

1 查询Student表的所有记录。
2 select * from student
3 Linq:
4     from s in Students
5     select s
6 Lambda:
7     Students.Select( s => s)
登入後複製
登入後複製

※按列查询

select sname,ssex,class from student 
3 Linq: 
4     from s in Students 
5     select new { 
6         s.SNAME, 
7         s.SSEX, 
8         s.CLASS
 9     }
 10 Lambda:
 11     Students.Select( s => new {
 12         SNAME = s.SNAME,SSEX = s.SSEX,CLASS = s.CLASS
 13     })
登入後複製
登入後複製

※distinct去重查询

 查询教师所有的单位即不重复的Depart列。
2 select distinct depart from teacher
3 Linq:
4     from t in Teachers.Distinct()
5     select t.DEPART
6 Lambda:
7     Teachers.Distinct().Select( t => t.DEPART)
登入後複製

※两个区间内查询

1 查询Score表中成绩在60到80之间的所有记录。
 2 select * from score where degree between 60 and 80
 3 Linq: 
 4     from s in Scores 
 5     where s.DEGREE >= 60 && s.DEGREE < 80
 6     select s 
 7 Lambda: 
 8     Scores.Where( 
 9         s => (
 10                 s.DEGREE >= 60 && s.DEGREE < 80
 11              )
 12     )
登入後複製
登入後複製

※在一个范围内查询

 select * from score where degree in (85,86,88)
 2 Linq:
 3     from s in Scores
 4     where (
 5             new decimal[]{85,86,88}
 6           ).Contains(s.DEGREE)
 7     select s
 8 Lambda:
 9     Scores.Where( s => new Decimal[] {85,86,88}.Contains(s.DEGREE))
登入後複製
登入後複製

※或关系查询

 查询Student表中"95031"班或性别为"女"的同学记录。
 2 select * from student where class =&#39;95031&#39; or ssex= N&#39;女&#39;
 3 Linq:
 4     from s in Students
 5     where s.CLASS == "95031"
 6        || s.CLASS == "女"
 7     select s
 8 Lambda:
 9     Students.Where(s => ( s.CLASS == "95031" || s.CLASS == "女"))
登入後複製
登入後複製

※排序

 以Class降序查询Student表的所有记录。
 2 select * from student order by Class DESC
 3 Linq:
 4     from s in Students
 5     orderby s.CLASS descending
 6     select s
 7 Lambda:
 8     Students.OrderByDescending(s => s.CLASS)
登入後複製
登入後複製

※行数查询

 select count(*) from student where class = &#39;95031&#39;
 2 Linq: 
 3     (    from s in Students 
 4         where s.CLASS == "95031"
 5         select s 
 6     ).Count() 
 7 Lambda: 
 8     Students.Where( s => s.CLASS == "95031" ) 
 9                 .Select( s => s)
 10                     .Count()
登入後複製
登入後複製

※平均值查询

 查询&#39;3-105&#39;号课程的平均分。
 2 select avg(degree) from score where cno = &#39;3-105&#39;
 3 Linq: 
 4     ( 
 5         from s in Scores 
 6         where s.CNO == "3-105"
 7         select s.DEGREE 
 8     ).Average() 
 9 Lambda:
 10     Scores.Where( s => s.CNO == "3-105")
 11             .Select( s => s.DEGREE)
登入後複製
登入後複製

※潜逃查询

查询Score表中的最高分的学生学号和课程号。
 2 select distinct s.Sno,c.Cno from student as s,course as c ,score as sc 
 3 where s.sno=(select sno from score where degree = (select max(degree) from score)) 
 4 and c.cno = (select cno from score where degree = (select max(degree) from score)) 
 5 Linq: 
 6     ( 
 7         from s in Students
 8         from c in Courses 
 9         from sc in Scores
 10         let maxDegree = (from sss in Scores
 11                         select sss.DEGREE
 12                         ).Max()
 13         let sno = (from ss in Scores
 14                 where ss.DEGREE == maxDegree
 15                 select ss.SNO).Single().ToString()
 16         let cno = (from ssss in Scores
 17                 where ssss.DEGREE == maxDegree
 18                 select ssss.CNO).Single().ToString()
 19         where s.SNO == sno && c.CNO == cno
 20         select new {
 21             s.SNO,
 22             c.CNO
 23         }
 24     ).Distinct()
登入後複製

※分组

 查询Score表中至少有5名学生选修的并以3开头的课程的平均分数。
 2 select avg(degree) from score where cno like &#39;3%&#39; group by Cno having count(*)>=5
 3 Linq: 
 4         from s in Scores 
 5         where s.CNO.StartsWith("3") 
 6         group s by s.CNO 
 7         into cc 
 8         where cc.Count() >= 5
 9         select cc.Average( c => c.DEGREE)
 10 Lambda:
 11     Scores.Where( s => s.CNO.StartsWith("3") )
 12             .GroupBy( s => s.CNO )
 13               .Where( cc => ( cc.Count() >= 5) )
 14                 .Select( cc => cc.Average( c => c.DEGREE) )
 15 Linq: SqlMethod
 16 like也可以这样写:
 17     s.CNO.StartsWith("3") or SqlMethods.Like(s.CNO,"%3")
登入後複製
登入後複製

※分组过滤

查询Score表中至少有5名学生选修的并以3开头的课程的平均分数。
 2 select avg(degree) from score where cno like &#39;3%&#39; group by Cno having count(*)>=5
 3 Linq: 
 4         from s in Scores 
 5         where s.CNO.StartsWith("3") 
 6         group s by s.CNO 
 7         into cc 
 8         where cc.Count() >= 5
 9         select cc.Average( c => c.DEGREE)
 10 Lambda:
 11     Scores.Where( s => s.CNO.StartsWith("3") )
 12             .GroupBy( s => s.CNO )
 13               .Where( cc => ( cc.Count() >= 5) )
 14                 .Select( cc => cc.Average( c => c.DEGREE) )
 15 Linq: SqlMethod
 16 like也可以这样写:
 17     s.CNO.StartsWith("3") or SqlMethods.Like(s.CNO,"%3")
登入後複製
登入後複製

※多表联合查询

 select sc.sno,c.cname,sc.degree from course as c,score as sc where c.cno = sc.cno
 2 Linq: 
 3     from c in Courses 
 4     join sc in Scores 
 5     on c.CNO equals sc.CNO
 6     select new 
 7     { 
 8         sc.SNO,c.CNAME,sc.DEGREE
 9     }
 10 Lambda:
 11     Courses.Join ( Scores, c => c.CNO,
 12                              sc => sc.CNO,
 13                              (c, sc) => new
 14                                         {
 15                                             SNO = sc.SNO,
 16                                             CNAME = c.CNAME,
 17                                             DEGREE = sc.DEGREE
 18                                         })
 19                 .Average()
登入後複製
登入後複製

 以上就是SQL、LINQ和Lambda表达式的内容,更多相关内容请关注PHP中文网(www.php.cn)!


本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

lambda 表達式在 C++ 中如何處理異常? lambda 表達式在 C++ 中如何處理異常? Apr 17, 2024 pm 12:42 PM

在C++中,使用Lambda表達式處理異常有兩種方法:使用try-catch區塊捕獲異常,並在catch區塊中處理或重新拋出異常。使用std::function類型的包裝函數,其try_emplace方法可以捕獲Lambda表達式中的異常。

用 C++ lambda 表達式實作多執行緒程式設計的優點是什麼? 用 C++ lambda 表達式實作多執行緒程式設計的優點是什麼? Apr 17, 2024 pm 05:24 PM

lambda表達式在C++多執行緒程式設計中的優點包括:簡潔性、靈活性、易於傳參和並行性。實戰案例:使用lambda表達式建立多執行緒,在不同執行緒中列印執行緒ID,展示了該方法的簡潔和易用性。

C++ lambda 表達式中閉包的意思是什麼? C++ lambda 表達式中閉包的意思是什麼? Apr 17, 2024 pm 06:15 PM

在C++中,閉包是能夠存取外部變數的lambda表達式。若要建立閉包,請擷取lambda表達式中的外部變數。閉包提供可重複使用性、資訊隱藏和延遲求值等優點。它們在事件處理程序等實際情況中很有用,其中即使外部變數被銷毀,閉包仍然可以存取它們。

C++ Lambda 表達式如何實作閉包? C++ Lambda 表達式如何實作閉包? Jun 01, 2024 pm 05:50 PM

C++Lambda表達式支援閉包,即保存函數作用域變數並供函數存取。語法為[capture-list](parameters)->return-type{function-body}。 capture-list定義要捕獲的變量,可以使用[=]按值捕獲所有局部變量,[&]按引用捕獲所有局部變量,或[variable1,variable2,...]捕獲特定變量。 Lambda表達式只能存取捕獲的變量,但無法修改原始值。

C++ lambda 表達式如何捕捉外部變數? C++ lambda 表達式如何捕捉外部變數? Apr 17, 2024 pm 04:39 PM

在C++中捕捉外部變數的lambda表達式有三種方法:按值擷取:建立一個變數副本。按引用擷取:獲得變數引用。同時按值和引用捕獲:允許捕獲多個變量,按值或按引用。

C++ 函式呼叫 Lambda 表達式:參數傳遞與傳回值的回呼最佳化 C++ 函式呼叫 Lambda 表達式:參數傳遞與傳回值的回呼最佳化 May 03, 2024 pm 12:12 PM

在C++中,可以使用Lambda表達式作為函數參數,實現回呼函數的靈活性。具體而言:參數傳遞:透過std::function包裝Lambda表達式,以函數指標形式傳遞給函數。傳回值處理:使用std::function宣告回呼函數指標時指定傳回值類型。實戰案例:優化GUI事件處理中的回調,避免創建不必要的物件或函數指針,提高程式碼簡潔性和可維護性。

如何使用 C++ lambda 表達式執行延遲求值? 如何使用 C++ lambda 表達式執行延遲求值? Apr 17, 2024 pm 12:36 PM

如何使用C++lambda表達式執行延遲求值?使用lambda表達式建立延遲求值的函數物件。延遲計算推遲到需要時才執行。僅當需要時才計算結果,提高效能。

如何用 C++ lambda 表達式取代函數指標? 如何用 C++ lambda 表達式取代函數指標? Apr 17, 2024 pm 04:24 PM

以lambda表達式取代函數指標可提升可讀性、減少樣板程式碼並提高重用性。具體而言,lambda表達式採用以下語法:[capturelist](parameterlist)->returntype{body},並可用於對向量排序等實戰案例中,提升程式碼簡潔性和可維護性。

See all articles