LINQ的书写格式如下:
from 临时变量 in 集合对象或数据库对象
where 条件表达式
[order by条件]
select 临时变量中被查询的值
[group by 条件]
Lambda表达式的书写格式如下:
(参数列表) => 表达式或者语句块
其中: 参数个数:可以有多个参数,一个参数,或者无参数。
参数类型:可以隐式或者显式定义。
表达式或者语句块:这部分就是我们平常写函数的实现部分(函数体)。
查询操作符:http://blog.csdn.net/anchenyanyue/article/details/6732166
·Distinct -过滤集合中的相同项;延迟
·Union-连接不同集合,自动过滤相同项;延迟
·Concat-连接不同集合,不会自动过滤相同项;延迟
·Intersect-获取不同集合的相同项(交集);延迟
·Except-从某集合中删除其与另一个集合中相同的项;延迟
·Skip-跳过集合的前n个元素;延迟
·Take-获取集合的前n个元素;延迟
·SkipWhile-直到某一条件成立就停止跳过;延迟
·TakeWhile-直到某一条件成立就停止获取;延迟
·Single-根据表达式返回集合中的某一元素;不延迟
·SingleOrDefault-根据表达式返回集合中的某一元素(如果没有则返回默认值);不延迟
·Reverse-对集合反向排序;延迟
·SelectMany- Select选择(一对多);延迟
查询操作符
1.查询全部
实例 Code
查询Student表的所有记录。select * fromstudent
Linq:from s inStudentsselects
Lambda:
Students.Select( s=> s)
2 按条件查询全部:
实例 Code
查询Student表中的所有记录的Sname、Ssex和Class列。select sname,ssex,class fromstudent
Linq:from s inStudentsselect new{
s.SNAME,
s.SSEX,
s.CLASS
}
Lambda:
Students.Select( s=> new{
SNAME= s.SNAME,SSEX = s.SSEX,CLASS =s.CLASS
})
View Code
3.distinct 去掉重复的
实例 Code
查询教师所有的单位即不重复的Depart列。select distinct depart fromteacher
Linq:from t inTeachers.Distinct()selectt.DEPART
Lambda:
Teachers.Distinct().Select( t=> t.DEPART)
View Code
4.连接查询 between and
实例 Code
查询Score表中成绩在60到80之间的所有记录。select * from score where degree between 60 and 80Linq:from s inScoreswhere s.DEGREE >= 60 && s.DEGREE < 80
selects
Lambda:
Scores.Where(
s=>(
s.DEGREE>= 60 && s.DEGREE < 80)
)
View Code
5.在范围内筛选 In
实例 Codeselect * from score where degree in (85,86,88)
Linq:from s inScoreswhere(new decimal[]{85,86,88}
).Contains(s.DEGREE)selects
Lambda:
Scores.Where( s=> new Decimal[] {85,86,88}.Contains(s.DEGREE))
View Code
6.or 条件过滤
实例 Code
查询Student表中"95031"班或性别为"女"的同学记录。select * from student where class ='95031' or ssex= N'女'Linq:from s inStudentswhere s.CLASS == "95031"
|| s.CLASS == "女"
selects
Lambda:
Students.Where(s=> ( s.CLASS == "95031" || s.CLASS == "女"))
View Code
7.排序
实例 Code
以Class降序查询Student表的所有记录。select * fromstudent order by Class DESC
Linq:from s inStudentsorderbys.CLASS descendingselects
Lambda:
Students.OrderByDescending(s=> s.CLASS)
View Code
8.count()行数查询
实例 Codeselect count(*) from student where class = '95031'Linq:
(from s inStudentswhere s.CLASS == "95031"
selects
).Count()
Lambda:
Students.Where( s=> s.CLASS == "95031")
.Select( s=>s)
.Count()
View Code
9.avg()平均
实例 Code
查询'3-105'号课程的平均分。select avg(degree) from score where cno = '3-105'Linq:
(from s inScoreswhere s.CNO == "3-105"
selects.DEGREE
).Average()
Lambda:
Scores.Where( s=> s.CNO == "3-105")
.Select( s=> s.DEGREE)
View Code
10.子查询
实例 Code
查询Score表中的最高分的学生学号和课程号。select distinct s.Sno,c.Cno from student as s,course as c ,score asscwhere s.sno=(select sno from score where degree = (select max(degree) fromscore))
and c.cno= (select cno from score where degree = (select max(degree) fromscore))
Linq:
(from s inStudentsfrom c inCoursesfrom sc inScores
let maxDegree= (from sss inScoresselectsss.DEGREE
).Max()
let sno= (from ss inScoreswhere ss.DEGREE ==maxDegreeselectss.SNO).Single().ToString()
let cno= (from ssss inScoreswhere ssss.DEGREE ==maxDegreeselectssss.CNO).Single().ToString()where s.SNO == sno && c.CNO ==cnoselect new{
s.SNO,
c.CNO
}
).Distinct()
View Code
11.分组 过滤
实例 Code
查询Score表中至少有5名学生选修的并以3开头的课程的平均分数。select avg(degree) from score where cno like '3%' group by Cno having count(*)>=5Linq:from s inScoreswhere s.CNO.StartsWith("3")
group s by s.CNO
into ccwhere cc.Count() >= 5
select cc.Average( c =>c.DEGREE)
Lambda:
Scores.Where( s=> s.CNO.StartsWith("3") )
.GroupBy( s=>s.CNO )
.Where( cc=> ( cc.Count() >= 5) )
.Select( cc=> cc.Average( c =>c.DEGREE) )
Linq: SqlMethod
like也可以这样写:
s.CNO.StartsWith("3") or SqlMethods.Like(s.CNO,"%3")
View Code
12.分组
实例 Code
查询Score表中至少有5名学生选修的并以3开头的课程的平均分数。select avg(degree) from score where cno like '3%' group by Cno having count(*)>=5Linq:from s inScoreswhere s.CNO.StartsWith("3")
group s by s.CNO
into ccwhere cc.Count() >= 5
select cc.Average( c =>c.DEGREE)
Lambda:
Scores.Where( s=> s.CNO.StartsWith("3") )
.GroupBy( s=>s.CNO )
.Where( cc=> ( cc.Count() >= 5) )
.Select( cc=> cc.Average( c =>c.DEGREE) )
Linq: SqlMethod
like也可以这样写:
s.CNO.StartsWith("3") or SqlMethods.Like(s.CNO,"%3")
View Code
13. 多表查询
实例 Codeselect sc.sno,c.cname,sc.degree from course as c,score as sc where c.cno =sc.cno
Linq:from c inCourses
join scinScores
on c.CNO equals sc.CNOselect new{
sc.SNO,c.CNAME,sc.DEGREE
}
Lambda:
Courses.Join ( Scores, c=>c.CNO,
sc=>sc.CNO,
(c, sc)=> new{
SNO=sc.SNO,
CNAME=c.CNAME,
DEGREE=sc.DEGREE
})
.Average()
View Code
14. null
在C#中,存在一种特殊的类型,Nullable的类型,这个类型可以为空的状态。
在数据库中,如果类型允许为空,就会有NULL的字段
在Lamda查询表达式中,对于数据库中为空的情况也要特殊的注意一下
在SQL的查询中,如果存在为空的字段,例如------------------------------------table Test------------------------------------A B C1 NULL 2
2 true 2
3 false 2
------------------------------------我们要查询 不为真的情况,我们用select Count(*) from Test where B<>true此时查询的结果是只有一条------------------------------------A B C3 false 2
------------------------------------如果按照正常的逻辑来考虑,应该是2条的,如下------------------------------------A B C1 NULL 2
3 false 2
------------------------------------但是由于Null字段的特殊性,在查询的时候为select Count(*) from Test where B isNull 才能够查询到------------------------------------A B C1 NULL 2
------------------------------------这条记录,因此我们要查询这样的数据,就不能够用不等于进行查询,要用或者来进行查询select Count(*) from Test where B is Null or B=false在Linq的查询中同理,我们用Lamd表达式查询,如果为三态的情况,我们想要其中的另两个结果,此时也要用or来进行连接
如:
Tests 为表Test的集合
Tests.where(p=>p.B!=true) 这样查询时不会得到正确的结果的,原因很简单,就是因为Null的字段不会自动翻译
因此正确的查询结果是
Tests.where(p=>p.B==false||p.B==null)
此时查询就为正确的结果,当然我们可以利用这种特性,查询的时候可以查询所有的有效数据,避免掉那些为空的数据。
OK,关于Lambda查询和SQL查询 字段为空(NULL)的情况要注意了.
View Code
sql:ShippedDate IS NULL
linq:where o.ShippedDate==nulllamda: (o=> (o.ShippedDate == (DateTime?)null))
sql:ShippedDate IS NULL
linq: Nullable.Equals(o.ShippedDate,null)
lamda: (o=> Object.Equals (o.ShippedDate, null))
sql:ShippedDate IS NULL
linq: o.ShippedDate.Value==(DateTime?)nulllamda: (o=> ((DateTime?)(o.ShippedDate.Value) == (DateTime?)null))
sql:ShippedDate IS NULL
linq: System.Data.Linq.SqlClient.SqlMethods.Equals(o.ShippedDate.Value,null)
lamda:(o=> Object.Equals (o.ShippedDate.Value, null))
sql:NOT ([t0].[ShippedDate] IS NOT NULL)
linq:!o.ShippedDate.HasValue
lamda: (o=> !(o.ShippedDate.HasValue))
View Code
15.分组获取前几条
var lstCheckReportQuestionId = db.TCheckReportQuestion.Where(m => m.RID == gRid).Select(m =>m.QuestionID);var lstImage = from a indb.TInspectQuestionImagewherelstCheckReportQuestionId.Contains(a.QuestionID)selecta;//lamda:
var firstImage = lstImage.GroupBy(m => new { m.QuestionID }).SelectMany(m => m.OrderBy(p => p.ImageID).Take(1)).Select(m => new{
a1=m.ImageID,
a2=m.QuestionID,
a3=m.MiniImgUrl
}).ToList();//linq:
var lstInspectQuestionImage = (from a indb.TInspectQuestionImagewherelstCheckReportQuestionId.Contains(a.QuestionID)
group a by a.QuestionID into gselect new { QuestionID = g.Key, Source = g.OrderBy(m => m.ImageID).Take(1) })
.Select(m=> new { QuestionID = m.QuestionID, MiniImgUrl = m.Source.Select(p => p.MiniImgUrl) }).ToList();
View Code
16.空字段使用contains查询的解决办法
Name允许为空且在数据库中存在空值(NULL),使用contains会出现常见的报错
原理:Contains关键字的工作原理是返回一个bool值,当满足contains条件时返回true,否则返回false,以此来决定本条数据是否要获取,所以判断字段为空就直接用false来返回来跳过执行contains;
用法如下:var userlist= (IEnumerable)data.Where(t => (string.IsNullOrWhiteSpace(t.Name) ? false : t.Name.Contains(querystring));
View Code
17.case when
1.select中使用case when
linq代码:
Products.Select(P=> new{
ID=P.ProductID,
Name=P.Name,
Color=P.Color,
Price= (P.Color == "Red" ? P.StandardCost : (P.Color == "Black" ? P.StandardCost + 10: P.ListPrice))
});
sql原型:
SELECT ProductID, Name, Color,
CASE
WHEN Color= 'Red'THEN StandardCost
WHEN Color= 'Black' THEN StandardCost + 10ELSE ListPrice
END Price
FROM SalesLT.Product
View Code
2.where中使用case when
linq代码:
Products
.Where(P=> (P.Color == "Red" ? (P.StandardCost > 100) : (P.Color == "Black" ? P.ListPrice > 100 : P.ListPrice ==P.StandardCost)))
.Select(P=> new{
ID=P.ProductID,
Name=P.Name,
Color=P.Color,
StandardCost=P.StandardCost,
ListPrice=P.ListPrice
});
sql原型:
SELECT ProductID, Name, Color, StandardCost, ListPrice
FROM SalesLT.Product
WHERE (
(CASE
WHEN Color= 'Red'THEN
(CASE
WHEN StandardCost> 100 THEN 1WHEN NOT (StandardCost> 100) THEN 0ELSE NULL
END)
WHEN Color= 'Black'THEN
(CASE
WHEN ListPrice> 100 THEN 1WHEN NOT (ListPrice> 100) THEN 0ELSE NULL
END)
ELSE
(CASE
WHEN ListPrice= StandardCost THEN 1WHEN NOT (ListPrice= StandardCost) THEN 0ELSE NULL
END)
END))= 1
View Code
3.group by中使用case when
linq代码:
Products.GroupBy(P=> P.StandardCost > 1000?P.Color : P.SellStartDate.ToString())
sql原型:--Region Parameters
DECLARE @p0 Decimal(8,4) = 1000
--EndRegion
SELECT [t1].[value] AS [Key]
FROM (
SELECT
(CASE
WHEN [t0].[StandardCost]>@p0 THEN CONVERT(NVarChar(MAX),[t0].[Color])
ELSE CONVERT(NVarChar(MAX),[t0].[SellStartDate])
END) AS [value]
FROM [SalesLT].[Product] AS [t0]
) AS [t1]
GROUP BY [t1].[value]
GO
View Code
4.group by sum
select new{
TaskId=a.TaskID,
TaskName=a.TaskName,
ProjectId=a.ProjectID,
ProjectName=d.ProjectName,
QuestionId=b.QuestionID,
QuestionState=b.QuestState,
HouseId=c.BFID
})
group a bynew{ a.TaskId,a.TaskName,a.ProjectId,a.ProjectName } into tqselect new{
tq.Key,
QuestionCnt=tq.Count(),
QuestionSortOut= tq.Sum(m=>!new string[] {"0","1"}.Contains(m.QuestionState)? 1 : 0)
}
View Code
5.group by avg
var categories =
from p indb.Products
group p by p.CategoryID into gselect new{
g.Key,
ExpensiveProducts=
from p2 ingwhere p2.UnitPrice > g.Average(p3 =>p3.UnitPrice)selectp2
};
View Code
18. Aggregate
说明:根据输入的表达式获取聚合值;不延迟。即是说:用一个种子值与当前元素通过指定的函数来进行对比来遍历集合中的元素,符合条件的元素保留下来。如果没有指定种子值的话,种子值默认为集合的第一个元素。
Where
过滤;延迟
Select
选择;延迟
Distinct
查询不重复的结果集;延迟
Count
返回集合中的元素个数,返回INT类型;不延迟
LongCount
返回集合中的元素个数,返回LONG类型;不延迟
Sum
返回集合中数值类型元素之和,集合应为INT类型集合;不延迟
Min
返回集合中元素的最小值;不延迟
Max
返回集合中元素的最大值;不延迟
Average
返回集合中的数值类型元素的平均值。集合应为数字类型集合,其返回值类型为double;不延迟
Aggregate
根据输入的表达式获取聚合值;不延迟