SQL、LINQ和Lambda表達式

黄舟
發布: 2017-02-23 10:05:34
原創
1519 人瀏覽過


首先說說這三者完全是三種不同的東西,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)!


相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板