• LINQ to SQL系列 查询 使用LINQ to SQL做简单查询


    LINQ做查询是本分,我们看看LINQ的查询吧

    这篇文章使用的数据模型如下:

    还是上一篇提到的Student表,为了做查询我多添加了几个字段而已。

    在自动生成的DataContext中有Students属性,它的类型是Table<Student>对应数据库中的Student表,我们的查询对象就是它了。

    先来一个最简单的Query

    var query = from s in db.Students
                select s;
    

    上面的语句可以查询Student表的所有记录,但是它却不同于 SQL语句

    SELECT [StudentID]
          ,[Name]
          ,[Hometown]
          ,[Gender]
          ,[Birthday]
          ,[ClassID]
          ,[WeightInKg]
          ,[HeightInCm]
          ,[Desc]
      FROM [Test].[dbo].[Student]
    

    query的数据类型是IQueryable<Student> ,其字面意思是Student的可查询实例,通过这个query我们可以做很多种查询,当然包括上面的SQL语句。具体这个IQueryable实例会做那种查询和我们后续代码中如何使用它有关系,下面是几个例子:

    1. 使用query返回Student表中的记录数,代码如下

    using (var writer = new StreamWriter(@"E:\projects.2010\Test\LINQ2SQL_2\linq.sql", false, Encoding.UTF8))
    {
        //最简单的select
        using (DbAppDataContext db = new DbAppDataContext())
        {
            //设置Log打印到的地方
          db.Log = writer;
            var query = from s in db.Students
                        select s;
    
            //返回Student表中的记录数
          var cn = query.Count();
        }
    }
    

    上面query.Count()执行的SQL如下:

    SELECT COUNT(*) AS [value]
    FROM [dbo].[Student] AS [t0]
    -- Context: SqlProvider(Sql2005) Model: AttributedMetaModel Build: 4.0.30319.

    生成的sql语句很规范,取得Student表中的记录数 

    2.给这个IQuerable添加条件身高大于130cm,然后执行查询

    using (var writer = new StreamWriter(@"E:\projects.2010\Test\LINQ2SQL_2\linq.sql", false, Encoding.UTF8))
    {
        //最简单的select 
        using (DbAppDataContext db = new DbAppDataContext())
        {
            //设置Log属性,将生成的sql语句保存到文件中
            db.Log = writer;
            var query = from s in db.Students
                        select s;
    
            //打印身高大于132cm的Student
            foreach (var item in query.Where(s => s.HeightInCm > 132))
            {
                Console.WriteLine("{0}的身高是{1}cm", item.Name, item.HeightInCm);
            }
        }
    }

    其SQL语句如下:可以看到linq to sql对sql注入攻击有天然的免疫作用,它自动生成的sql语句是参数化的

    SELECT [t0].[StudentID], [t0].[Name], [t0].[Hometown], [t0].[Gender], [t0].[Birthday], [t0].[ClassID], [t0].[WeightInKg], [t0].[HeightInCm], [t0].[Desc] AS [Desc]
    FROM [dbo].[Student] AS [t0]
    WHERE [t0].[HeightInCm] > @p0
    -- @p0: Input Float (Size = -1; Prec = 0; Scale = 0) [132]
    -- Context: SqlProvider(Sql2005) Model: AttributedMetaModel Build: 4.0.30319.1

    我们可以对IQueryable附加条件限制,其实添加这个Where后的query和下面的语句是等价的。

    var query = from s in db.Students
                where s.HeightInCm > 132
                select s;

    那么如果我们的query实例中已经有条件后再加限制会是什么样子的呢,请看3

     3. 在query定义是有身高、体重两个查询条件,在使用query时我们又附加了一个Hometown在“多家营”的条件,看下代码和真实执行的sql情况

    using (var writer = new StreamWriter(@"E:\projects.2010\Test\LINQ2SQL_2\linq.sql", false, Encoding.UTF8))
    {
        //最简单的select 
        using (DbAppDataContext db = new DbAppDataContext())
        {
            //设置Log属性,将生成的sql语句保存到文件中
            db.Log = writer;
    
            //查询身高大于132并且体重大于30的Student
            var query = from s in db.Students
                        where s.HeightInCm > 132 && s.WeightInKg > 30
                        select s;
    
            //在query中用Where附加家乡在多家营的记录
            foreach (var item in query.Where(s => s.Hometown == "多家营"))
            {
                Console.WriteLine("{0}的身高是{1}cm", item.Name, item.HeightInCm);
            }
        }
    }
    

    SQL:

    SELECT [t0].[StudentID], [t0].[Name], [t0].[Hometown], [t0].[Gender], [t0].[Birthday], [t0].[ClassID], [t0].[WeightInKg], [t0].[HeightInCm], [t0].[Desc] AS [Desc]
    FROM [dbo].[Student] AS [t0]
    WHERE ([t0].[Hometown] = @p0) AND ([t0].[HeightInCm] > @p1) AND ([t0].[WeightInKg] > @p2)
    -- @p0: Input NVarChar (Size = 4000; Prec = 0; Scale = 0) [多家营]
    -- @p1: Input Float (Size = -1; Prec = 0; Scale = 0) [132]
    -- @p2: Input Float (Size = -1; Prec = 0; Scale = 0) [30]
    -- Context: SqlProvider(Sql2005) Model: AttributedMetaModel Build: 4.0.30319.1

    可以看出后附件的条件并非如我们常规理解附件到条件的最后,而是放到了最前面,这一点有可能对效率造成影响,是需要我们注意的。

    通过上面三点可以看出来linq to sql中的IQueryable并非等同于某一个sql语句,其具体要执行的sql语句和具体情况有关系。

    在query定义时可以很方便的添加排序规则,可以是一个或者n个,如下语句:

    //查询身高大于132并且体重大于30的Student,并按照StudentID升序排序,按照classID降序排序
    var query = from s in db.Students
                where s.HeightInCm > 132 && s.WeightInKg > 30
                orderby s.StudentID ascending, s.ClassID descending
                select s;
    

    本文完,后续系列会介绍join,多表查询等。

    linq to sql相关随笔:

    1.  从CUD开始,如何使用LINQ  to SQL插入、修改、删除数据

    2.  查询 使用LINQ to SQL做简单查询

    3.  查询 延迟加载与立即加载,使用LoadWith和AssociateWith

    4.  查询 inner join,left outer join

    5.  Linq to SQL中的聚合grouping having

    6.  LINQ to SQL查询优化,需要忧虑性能吗?

  • 相关阅读:
    基于 mockm 的一款 HBuilderX 插件
    css 加载中省略号动画
    定时获取远程文件并存储更新记录
    跨域实例和解决方案
    接口数据总是返回 null 如何回馈和处理
    get 请求中如何携带 body 参数
    看起来像一个 textarea 的 div
    js 高精度运算
    nodejs 服务终端使用 nodemon 运行脚本时实时输出
    解决 vue-cli3 多入口打包 BASE_URL is not defined
  • 原文地址:https://www.cnblogs.com/yukaizhao/p/linq_to_sql_select_2.html
Copyright © 2020-2023  润新知