SQL、LINQ和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.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 =‘95031‘ or ssex= N‘女‘
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 = ‘95031‘
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()
※平均值查询
查询‘3-105‘号课程的平均分。
2 select avg(degree) from score where cno = ‘3-105‘
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 ‘3%‘ 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 ‘3%‘ 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()
以上内容是本人查阅资料做的一些整理和总结,有不足之处请大家批评指正!
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。