zoukankan      html  css  js  c++  java
  • sql 、linq、lambda 查询语句的区别

    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 * from student
    Linq:
        from s in Students
        select s
    Lambda:
        Students.Select( s => s)

    2 按条件查询全部:

    实例 Code 
     查询Student表中的所有记录的Sname、Ssex和Class列。
    select sname,ssex,class from student
    Linq:
        from s in Students
        select 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 from teacher
    Linq:
        from t in Teachers.Distinct()
        select t.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 80
    Linq:
        from s in Scores
        where s.DEGREE >= 60 && s.DEGREE < 80
        select s
    Lambda:
        Scores.Where(
            s => (
                    s.DEGREE >= 60 && s.DEGREE < 80
                 )
        )
    View Code

    5.在范围内筛选 In

    实例 Code 
    select * from score where degree in (85,86,88)
    Linq:
        from s in Scores
        where (
                new decimal[]{85,86,88}
              ).Contains(s.DEGREE)
        select s
    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 in Students
        where s.CLASS == "95031"
           || s.CLASS == ""
        select s
    Lambda:
        Students.Where(s => ( s.CLASS == "95031" || s.CLASS == ""))
    View Code

    7.排序

    实例 Code 
    以Class降序查询Student表的所有记录。
    select * from student order by Class DESC
    Linq:
        from s in Students
        orderby s.CLASS descending
        select s
    Lambda:
        Students.OrderByDescending(s => s.CLASS)
    View Code

    8.count()行数查询

    实例 Code 
    select count(*) from student where class = '95031'
    Linq:
        (    from s in Students
            where s.CLASS == "95031"
            select s
        ).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 in Scores
            where s.CNO == "3-105"
            select s.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 as sc
    where s.sno=(select sno from score where degree = (select max(degree) from score))
    and c.cno = (select cno from score where degree = (select max(degree) from score))
    Linq:
        (
            from s in Students
            from c in Courses
            from sc in Scores
            let maxDegree = (from sss in Scores
                            select sss.DEGREE
                            ).Max()
            let sno = (from ss in Scores
                    where ss.DEGREE == maxDegree
                    select ss.SNO).Single().ToString()
            let cno = (from ssss in Scores
                    where ssss.DEGREE == maxDegree
                    select ssss.CNO).Single().ToString()
            where s.SNO == sno && c.CNO == cno
            select 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(*)>=5
    Linq:
            from s in Scores
            where s.CNO.StartsWith("3")
            group s by s.CNO
            into cc
            where 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(*)>=5
    Linq:
            from s in Scores
            where s.CNO.StartsWith("3")
            group s by s.CNO
            into cc
            where 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. 多表查询

    实例 Code 
    select sc.sno,c.cname,sc.degree from course as c,score as sc where c.cno = sc.cno
    Linq:
        from c in Courses
        join sc in Scores
        on c.CNO equals sc.CNO
        select 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              C
     1               NULL           2
     2               true           2
     3               false          2
    ------------------------------------
    我们要查询 不为真的情况,我们用
     
     select Count(*) from Test where B<>true
    此时查询的结果是只有一条
    ------------------------------------
     A               B              C
     3               false          2
    ------------------------------------
    如果按照正常的逻辑来考虑,应该是2条的,如下
    ------------------------------------
     A               B              C
     1               NULL           2
     3               false          2
    ------------------------------------
    但是由于Null字段的特殊性,在查询的时候为
    
     select Count(*) from Test where B is Null 才能够查询到
    ------------------------------------
     A               B              C
     1               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==null  
    lamda: (o => (o.ShippedDate == (DateTime?)null))  
    
    sql:ShippedDate IS NULL  
    linq: Nullable<DateTime>.Equals(o.ShippedDate,null) 
    lamda: (o => Object.Equals (o.ShippedDate, null))  
    
    sql:ShippedDate IS NULL  
    linq: o.ShippedDate.Value==(DateTime?)null  
    lamda: (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 in db.TInspectQuestionImage
                                           where lstCheckReportQuestionId.Contains(a.QuestionID)
                                           select a;
    //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 in db.TInspectQuestionImage
                                                           where lstCheckReportQuestionId.Contains(a.QuestionID)
                                                           group a by a.QuestionID into g
                                                           select 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<User>)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 + 10
          ELSE 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 1
            WHEN NOT (StandardCost > 100) THEN 0
            ELSE NULL
           END)
        WHEN Color = 'Black' THEN 
          (CASE 
            WHEN ListPrice > 100 THEN 1
            WHEN NOT (ListPrice > 100) THEN 0
            ELSE NULL
           END)
        ELSE 
          (CASE 
            WHEN ListPrice = StandardCost THEN 1
            WHEN NOT (ListPrice = StandardCost) THEN 0
            ELSE 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 by new { a.TaskId,a.TaskName,a.ProjectId,a.ProjectName } into tq
                        select 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 in db.Products
        group p by p.CategoryID into g
        select new {
            g.Key, 
            ExpensiveProducts =
                from p2 in g
                where p2.UnitPrice > g.Average(p3 => p3.UnitPrice)
                select p2
        };
    View Code

     18. Aggregate

    说明:根据输入的表达式获取聚合值;不延迟。即是说:用一个种子值与当前元素通过指定的函数来进行对比来遍历集合中的元素,符合条件的元素保留下来。如果没有指定种子值的话,种子值默认为集合的第一个元素。

    Where 过滤;延迟
    Select 选择;延迟
    Distinct 查询不重复的结果集;延迟
    Count 返回集合中的元素个数,返回INT类型;不延迟
    LongCount 返回集合中的元素个数,返回LONG类型;不延迟
    Sum 返回集合中数值类型元素之和,集合应为INT类型集合;不延迟
    Min 返回集合中元素的最小值;不延迟
    Max 返回集合中元素的最大值;不延迟
    Average 返回集合中的数值类型元素的平均值。集合应为数字类型集合,其返回值类型为double;不延迟
    Aggregate 根据输入的表达式获取聚合值;不延迟
  • 相关阅读:
    杜教筛
    虚树
    带修莫队
    线性基
    区间修改区间求和cdq分治
    矩阵快速幂求斐波那契数列
    点分治成品
    Codeforces Round #542 [Alex Lopashev Thanks-Round] (Div. 1) C(二分+KMP)
    线性筛
    矩阵快速幂
  • 原文地址:https://www.cnblogs.com/love201314/p/4767065.html
Copyright © 2011-2022 走看看