.NET技术学习——LINQ

目录

1.LINQ 概述

2.LINQ查询基础

2.1 查询形式

2.2 查询表达式

2.3 标准查询运算符

2.4 LINQ语言特性

2.5 Func委托与匿名方法

2.6 Lambda表达式

3. LINQ实际应用 

3.1 新建LINQ to SQL类

3.2  LINQ数据分页查询


1.LINQ 概述

 LINQ(Language-Integrated Query,语言集成查询)是微软在.NET Framework 3.5版本引入的新功能,它能够将查询功能直接引入.Net Framework所支持的编程语言中。

如图所示,LINQ主要由LINQ to Objects、LINQ to ADO.NET、LINQ to XML三部分组成。其中:

  • LINQ to Objects:可以查询是实现了Ienumerable或Ienumerable<T>的集合,即任意可枚举的集合。
  • LINQ to ADO.NET:
    1. LINQ to SQL:可查询基于关系型数据库的数据,并进行CRUD等操作。
    2. LINQ to DataSet:对DataSet对象进行检索/过滤/排序等操作。
  • LINQ to XML:可对XML结构数据进行查询或操作。

2.LINQ查询基础

2.1 查询形式

  • Method syntax 方法语法

通过方法调用的形式调用LINQ查询,这些方法是一组命令式的,标准查询运算符形式的方法,并如SQL语句那样指明调用顺序。

string[] testStrs = new String[] { "This", "is", "my", "home" };
List<string> splitList = testStrs.Where(x => x.Length == 2).ToList();
foreach (string v in splitList) Console.Write(v + "\t");

输出:is  my

  • Query syntax 查询语法

查询语法是声明式的,类似SQL语句的查询子句,编译器会将其翻译成方法调用的形式。

string[] testStrs = new String[] { "This", "is", "my", "home" };
var splitList = from str in testStrs where str.Length == 2 select str;
foreach (object v in splitList) Console.Write(v + "\t");

输出:is  my

2.2 查询表达式

LINQ查询表达式有一个或者多个LINQ查询子句按照一定的规则组成,其中查询子句包括:

  • from ...  in:指定数据源和范围变量,这里的范围变量指数据源中的每一个元素

  • where:筛选条件

  • select:指定查询结果的类型和表现形式

  • orderby:对查询结果进行排序(降序/升序)

  • group ... by:对查询结果进行分组

  • into:引用join、group和select子句的结果

  • join ... on:连接多个查询操作的数据源

  • let:引入用于存储查询表达式中子表达式结果的范围变量,这里的范围变量指局部变量

LINQ查询表达式必须包括from子句,并且以from子句开头。下面是一个完整的例子:

    List<Scores> scores = GetScores();
    List<Student> students = GetStudents();
    var list = from stu in students
               join score in scores on stu.ID equals score.StudentID
               let sum = score.Chinese + score.Math + score.English   //定义临时变量sum
               where sum / 3 > 60
               group stu by new { stu.Age } into result
               orderby result.Key.Age descending
               select new { Age = result.Key.Age, Count = result.Count() };

2.3 标准查询运算符

LINQ标准查询运算符是有一系列API方法组成,并支持查询任何数组或集合对象。其中,被查询的集合必须实现IEnumberable<T>接口。常用的标准查询运算符(查询方法)有:

  • Select:同select子句

  • Where:同where子句

  • Take:指定要获取的元素个数,同SQL中的top语句

  • Skip:跳过指定的元素个数开始获取

  • Join:对两个对象执行内连接

  • GroupBy:同group by子句

  • OrderBy/ThenBy:OrderBy同orderby子句,ThenBy可对更多的元素进行排序

  • Count:返回集合中元素的个数

  • Sum:返回集合中某一项值得总和

  • Min:返回元素中最小的值

  • Max:返回元素中最大的值

下面是一个完整的例子:

List<Scores> scores = new List<Scores>();
List<Student> students = new List<Student>();

var JoinData = students.Join(scores,                    //内连接数据源
                             stu => stu.ID,             //内连接外键
                             score => score.StudentID,  //内连接主键
                             (stu, score) => new { Student = stu, Scores = score });  //指定查询结果
var ResultList = JoinData.Where( W => W.Scores.Chinese > 60)
                         .GroupBy(G => G.Student.Age)
                         .OrderByDescending(O => O.Key)  //OrderBy默认为升序,OrderByDescending降序
                         .Select(S => new { Age = S.Key, Count = S.Count()});

2.4 LINQ语言特性

  1. 隐式类型: var关键字声明变量,编译器通过变量所赋的值来推导数据类型,考虑到可读性,尽量显示指明数据类型。
  2. 匿名类型:通过var关键字和new关键字实现创建一个匿名类型,例:var obj = new { Name = "大宝哥" };
  3. 对象初始化器:结合前面两个特性,例:var stu = new Student(){ Name = "大宝哥" };

2.5 Func委托与匿名方法

Func是一个泛型委托,为了方便理解可以将其当做方法的数据类型,通过参数来区分。由于是泛型委托,其参数及返回值由开发者自行决定,注意输入参数可以有0~16个。

            int GetSum(int a, int b) { return a + b; } //定义一个求和方法
            Func<int, int, int> sum = GetSum;  //声明并初始化一个Func委托
            int result = sum(2, 3);            //调用Func委托

 这边查看定义的Func委托sum说明,可以看出声明类型中Func<int,int,int>的3个int参数,前两个泛型参数为调用方法GetSum中的参数类型,最后一个泛型参数为GetSum方法的返回值。 

对于上面的显式声明的委托及调用方法,还可以通过前面说的匿名方法来定义委托的回调方法。

            Func<int, int, int> sum = delegate (int a, int b)
            {
                retrun a +b;
            }

2.6 Lambda表达式

Lambda表达式是在Func泛型委托和匿名方法的基础上,再进一步对代码进行简化,将委托的回调方法简化到只有参数列表和方法体。“=>”符号左边为表达式的参数列表,右边为方法体,参数列表可包含0到多个参数,声明方式和所要调用的方法形参格式一样。例如,将2.5示例方法中的delegate关键字舍去,可以简化为

            Func<int, int, int> sum = (int a, int b) => { retrun a +b; }

若只有一个参数的情况,可以省去参数列表两边的括号 

            Func<int, int> sum =  a => { retrun a * 2; }

 注意,若没有参数的情况,需要保留一个空的括号来表示

            Func<int, int> sum =  () => { retrun 3 * 2; }

3. LINQ实际应用 

LINQ本质上就是对数据集合的查询,不论是List、Dictionary等IEnumerable集合,还是XML、DB等,都需要先连接到数据源。这边单独讲下LINQ to SQL,其他的大同小异不做阐述。

3.1 新建LINQ to SQL类

若在Visual Studio中没有找到“LINQ to SQL 类”,则在VS的“工具”菜单中,选择“获取工具和功能”打开Visual Studio Installer

 在“单个组件”选项下找到并勾选“LINQ to SQL 工具”后,点击“修改”

 继续前面新建LINQ to SQL类的操作,选择“LINQ to SQL类”并创建后,会在项目下生成一个dbml文件

到这一步就要执行连接数据库的操作了,连接DB的操作过程这边不做阐述。

连接完成后打开dbml文件,将所需操作的数据库表拖动至dbml文件页面空白处,这边就会生成实例化操作数据库的上下文Context类,同EF一样通过Context类获取并操作数据。

        CityDataContext cdc = new CityDataContext();
        var findResult = cdc.City.Where( c => c.Name.Equals("Shanghai"));

这边要注意的是对象关系设计器(O/R设计器)仅支持用于 SQL Server 的.NET Framework 数据提供程序 (System.Data.SqlClient),途中用了MySQL数据库,将左边数据库表拖放至dbml文件中时出现错误。

若不想更改数据库的话,建议使用其他对数据库数据操作的方式,如ODBC,EF等获取数据源后再进行LINQ操作。 

3.2  LINQ数据分页查询

        /// <summary>
        /// 获取页数据方法
        /// </summary>
        /// <param name="index">要获取的页码</param>
        /// <param name="pageSize">每页数据条目数</param>
       public void GetPageData(int index, int pageSize) 
        {
            CityDataContext cdc = new CityDataContext();
            var findResult = cdc.City.Where( c => c.Name.Length > 3);  //获取数据源并筛选结果
            
            //根据传入分页信息参数计算需要跳过的数据条数
            int skip = (index - 1) * pageSize;
            //跳过计算后的数据条数并获取要获取的数据条数
            var pageResult = findResult.Skip(skip).Take(pageSize);

            //显示数据操作......
        }

  • 10
    点赞
  • 70
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值