语言集成查询(Language-Integrated Query),简称LINQ,.NET中的LINQ体系如下图所示:

 

在编程语言层次,LINQ对于不同的数据源提供了相同的查询语法,方便了程序员操作不同的数据源。

可查询类型

LINQ之所以能够使用相同的语法操作不同的数据源,是因为和LINQ直接打交道的是可查询类型而非数据源,在LINQ中,直接或间接实现了IEnumerable<T>接口的类型称为可查询类型, .NET中如:List<T>Dictionary<TKey,TValue>,数组(由CLR负责隐式实现IEnumerable<T>接口)等,实现了IEnumerable<T>接口。
IQueryable<out T>继承自IEnumerable<T>,是个标记接口。

可查询类型无需额外操作即可进行LINQ操作,若数据源在内存中不以可查询类型的形式存在,那么LINQ提供程序必须要先将数据源转换为可查询类型,如LINQ to XML将XML文件转换为可查询的XElement类型:
 XElement contacts = XElement.Load(@"c:\myContactList.xml");

LINQ 提供程序

LINQ提供程序(LINQ Provider)提供了对特定的数据源进行标准的LINQ操作及一些扩展操作(如:LINQ to XML),不同的LINQ提供程序对于一些相同名称的扩展方法会提供不同的实现方式。.NET中预定义的LINQ提供程序包括:LINQ to ObjectLINQ to XML (C#)LINQ to SQLLINQ to DataSetLINQ to Entities
LINQ to SQL不建议使用,用LINQ to Entities来替代。

LINQ查询包含三个步骤:

  1. 获取数据源
  2. 创建查询语句
  3. 执行查询

LINQ查询方式

  • LINQ 表达式(又称为查询表达式
    from关键字开头,select关键字结尾。

  • 扩展方法(又称为标准查询
    System.Linq.Enumerable类和System.Linq.Queryable类,分别针对IEnumerable<T>IQueryable<T>接口进行的扩展。.NET也提供了几个对IEnumerable和IQueryable接口进行操作的扩展方法,如: Cast<TResult>OfType<TResult>

  • LINQ 表达式和扩展方法混合使用

    (from e in Employees
    where e.Salary>
    select e).ToList()

LINQ表达式和扩展方法对比:

LINQ表达式和扩展方法在编译后的代码没有什么区别

  • 对于排序、分组、联合查询使用LINQ表达式更为方便
//以排序为例,使用年龄、姓名、邮箱进行排序,
//LINQ表达式中使用逗号分隔排序字段,而扩展方法则需要多次调用相应的扩展方法
var result= from e in Employees
where e.Age> && e.Salary>
orderby e.Age,e.Name,e.Email
select e; //等价的扩展方法
var result=Employees
.Where(e=>e.Age> && e.Salary>)
.OrderBy(e=>e.Age)
.ThenBy(e=>e.Name)
.ThenBy(e=>e.Email);
  • 扩展方法能够提供比LINQ表达式更复杂的查询
//取第26行到36行范围内的数据
var result=Employees.Skip().Take(); //使用LINQ表达式我表示写不出来......

LINQ表达式是对常用扩展方法在语法层面上的简化,LINQ表达式有着更好的可读性,在编译时LINQ表达式会被转化为对扩展方法的调用

LINQ查询特点:

  • 延迟查询
    若查询表达式的返回结果是IEnumerable<T>类型,则在声明查询表达式时不会执行查询,而是在迭代查询变量时才进行查询。贴一幅MSDN上的经典LINQ查询流程图(延迟查询):

     
  • 立即查询
    若查询表达式返回单个值或者使用了ToList<T>ToArray<T>等方法时会执行立即查询,因为这些操作会遍历数据。

一句话总结,若查询表达式不包含对数据源的遍历操作则执行延迟查询,否则会进行立即查询

LINQ表达式中的查询关键字

表格中的英文没什么难点,就不翻译了 :)

关键字 描述
from Specifies a data source and a range variable (similar to an iteration variable).
where Filters source elements based on one or more Boolean expressions separated by logical AND and OR operators.
select Specifies the type and shape that the elements in the returned sequence will have when the query is executed.
group Groups query results according to a specified key value.
into Provides an identifier that can serve as a reference to the results of a join, group or select clause.
orderby Sorts query results in ascending or descending order based on the default comparer for the element type.
join Joins two data sources based on an equality comparison between two specified matching criteria.
let Introduces a range variable to store sub-expression results in a query expression.
in Contextual keyword in a join clause.
on Contextual keyword in a join clause.
equals Contextual keyword in a join clause.
by Contextual keyword in a group clause.
ascending Contextual keyword in an orderby clause.
descending Contextual keyword in an orderby clause.

两个接口

在LINQ中,一个查询表达式被编译为表达式树或者委托,查询结果为IEnumerable<T>类型则被编译为委托,查询结果是IQueryableIQueryable<T>类型则被编译为表达式树,在运行时表达式树会被解析为适合于数据源的查询语句。

  • System.Collection.Generic.IEnumerable<T>
    IEnumerable先将数据放到本地内存中,然后再执行过滤操作(如果有的话),适合于对当前进程中的数据进行查询操作,如:LINQ to XMLLINQ to Object
  • System.Linq.IQueryable<T>
    在执行查询操作时,IQueryable先在服务器端进行过滤操作(如果有的话),然后再将数据放到本地内存中。
    IQueryable适合使用对进程外(如数据库)的数据进行查询操作,如:LINQ to Entities

两个命名空间

System.Linq

System.Linq命名空间中包含用于LINQ查询的类和接口

System.Linq.Expressions

System.Linq.Expressions 命名空间包含了用于创建表达式树的类、 接口。

LINQ的优缺点

优点

  1. 对不同的数据源提供了几乎一致的查询操作,这可使我们更多的去关注业务逻辑而非对数据源的操作
  2. 提供编译期的类型检查
  3. 在书写LINQ查询表达式时可以使用Visual Studio的智能提示
  4. 调试方便

缺点

  1. 对于复杂的查询操作显得力不从心
  2. 容易写出性能不高的查询表达式

结语

本篇是自己学习LINQ的总结,不求面面俱到。通篇以文字叙述为主,辅以少量代码,若有错误希望大家指出。

工具推荐

LINQ Pad是一款轻量级的数据查询工具,在LINQ Pad中可以使用LINQ表达式、扩展方法、SQL语句等对数据库进行操作,简单易用功能强大。

书目推荐:

《LINQ Interview Questions Answers》

参考文章

Introduction to LINQ Queries (C#)
Standard Query Operators Overview (C#)
Query Expression Syntax for Standard Query Operators (C#)
Data Transformations with LINQ (C#)
LINQ provider basics
Enabling a Data Source for LINQ Querying
LINQ: Building an IQueryable Provider – Part I

版权声明

本文为作者原创,版权归作者雪飞鸿所有。 转载必须保留文章的完整性,且在页面明显位置处标明原文链接

如有问题, 请发送邮件和作者联系。

.NET中数据访问方式(一):LINQ的更多相关文章

  1. 白话LINQ系列2---以代码演进方式学习LINQ必备条件

    今天,我们通过一个简单的示例代码的演进过程,来学习LINQ必备条件:隐式类型局部变量:对象集合初始化器:委托:匿名函数:lambda表达式:扩展方法:匿名类型.废话不多说,我们直接进入主题. 一.实现 ...

  2. 关于php中数据访问的几点补充

    前几篇文章说了,parent.self.static关键字的使用,parent可以访问父类的静态方法和静态变量,self和static可以访问本类的静态成员等等,但实际上他们还有其他作用,来看一下: ...

  3. .NET 中数据访问用的 DBHelper(Sql Server) 类

    public class DBHelper { private static string DBConnectString = "Data Source=.;Initial Catalog= ...

  4. DriverStudio开发PCI设备DMA数据传输

    DriverWizard向导可以创建基本的wDM驱动程序框架,包括总线类型,地址空间,中断源,DMA资源,以及IOCTL(i/o控制代码)的定义等等.详细情况可参看DriverStudio的帮助文档, ...

  5. SharePoint—用REST方式访问列表

    REST的定义与作用 在SharePoint 2010中,基本上有如下几种数据访问方式: 服务器端对象模型 LINQ to SharePoint Web Service 客户端对象模型 ADO.NET ...

  6. SpringBoot定时任务 - 集成quartz实现定时任务(单实例和分布式两种方式)

    最为常用定时任务框架是Quartz,并且Spring也集成了Quartz的框架,Quartz不仅支持单实例方式还支持分布式方式.本文主要介绍Quartz,基础的Quartz的集成案例本,以及实现基于数 ...

  7. Code First开发系列之管理数据库创建,填充种子数据以及LINQ操作详解

    返回<8天掌握EF的Code First开发>总目录 本篇目录 管理数据库创建 管理数据库连接 管理数据库初始化 填充种子数据 LINQ to Entities详解 什么是LINQ to ...

  8. 8天掌握EF的Code First开发系列之3 管理数据库创建,填充种子数据以及LINQ操作详解

    本文出自8天掌握EF的Code First开发系列,经过自己的实践整理出来. 本篇目录 管理数据库创建 管理数据库连接 管理数据库初始化 填充种子数据 LINQ to Entities详解 什么是LI ...

  9. LINQ浅析

    在C# 3.0之前,我们对不同的数据源(数据集合.SQL 数据库.XML 文档等等)进行操作(查询.筛选.投影等等),会使用不同的操作方式. C# 3.0中提出了LINQ(Language Integ ...

随机推荐

  1. OSS最新进度汇报(2.25)

    OSS系列最新进度情况如下:一. OSS.Social进度 1. 客服接口升级至新客服接口 2. BaseRecMsg中RecMsg字符串类型修改为xml类型 3. 添加Redis缓存注册实现,代码见 ...

  2. iOS 快速集成启动页广告

    前言 由于项目中要用到启动页广告,所以做了简单的研究,同时借鉴网易新闻和蘑菇街的交互写了一个简单的demo,现在写出来供大家参考,可能由于个人局限会有一些bug和不完善的地方,也希望大家能够友善提醒和 ...

  3. 获取元素最终的background-color

    通常我们都会先获取元素,然后得到style对象获取对应的css属性值: 下面,假设我定义一个div并在css中给定了指定的background-color: 这里并没有考虑!important/内联的 ...

  4. 【疑问】css

    1.p{float:left}好像意思是p后面的元素往左浮动的意思啊!!2.ff下,button的文字好像没法垂直居中2.1 button垂直对齐,其line-height似乎需要减2px(依边框宽度 ...

  5. MySQL索引的使用方式

    一,create CREATE INDEX可对表增加普通索引或UNIQUE索引. CREATE INDEX index_name ON table_name (column_list) CREATE ...

  6. Django之Model世界

    Model 到目前为止,当我们的程序涉及到数据库相关操作时,我们一般都会这么搞: 创建数据库,设计表结构和字段 使用MySQLdb 来连接数据库,并编写数据访问层代码 业务逻辑层去调用数据访问层执行数 ...

  7. LeetCode 笔记总结

    前言 之前把一些LeetCode题目的思路写在了本子上,现在把这些全都放到博客上,以后翻阅比较方便. 题目 99.Recover Binary Search Tree 题意 Two elements ...

  8. Git基础教程(二)

    继续上篇Git基础教程(一),在开篇之前,先回顾一下上篇中的基本命令. 配置命令:git config --global * 版本库初始化:git init 向版本库添加文件:git add * 提交 ...

  9. 学习PHP一个月的感受

    学习PHP将近一个月了,接触IT这个行业也是从去年开始的,在这之前,IT行业只是耳闻,并不是很了解.接触IT这个行业以后,我最大的感受是,学起来并不是很困难,难的是要去精通它,我们必须时刻保持一颗学徒 ...

  10. 1179: [Apio2009]Atm

    1179: [Apio2009]Atm Time Limit: 15 Sec  Memory Limit: 162 MBSubmit: 1629  Solved: 615[Submit][Status ...