.NET中数据访问方式(一):LINQ
语言集成查询(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 Object、LINQ to XML (C#)、LINQ to SQL、LINQ to DataSet、LINQ to Entities。LINQ to SQL不建议使用,用LINQ to Entities来替代。
LINQ查询包含三个步骤:
- 获取数据源
- 创建查询语句
- 执行查询
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>类型则被编译为委托,查询结果是IQueryable或IQueryable<T>类型则被编译为表达式树,在运行时表达式树会被解析为适合于数据源的查询语句。
- System.Collection.Generic.IEnumerable<T>
IEnumerable先将数据放到本地内存中,然后再执行过滤操作(如果有的话),适合于对当前进程中的数据进行查询操作,如:LINQ to XML、LINQ to Object。
- System.Linq.IQueryable<T>
在执行查询操作时,IQueryable先在服务器端进行过滤操作(如果有的话),然后再将数据放到本地内存中。IQueryable适合使用对进程外(如数据库)的数据进行查询操作,如:LINQ to Entities。
两个命名空间
System.Linq
System.Linq命名空间中包含用于LINQ查询的类和接口
System.Linq.Expressions
System.Linq.Expressions 命名空间包含了用于创建表达式树的类、 接口。
LINQ的优缺点
优点
- 对不同的数据源提供了几乎一致的查询操作,这可使我们更多的去关注业务逻辑而非对数据源的操作
- 提供编译期的类型检查
- 在书写LINQ查询表达式时可以使用Visual Studio的智能提示
- 调试方便
缺点
- 对于复杂的查询操作显得力不从心
- 容易写出性能不高的查询表达式
结语
本篇是自己学习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的更多相关文章
- 白话LINQ系列2---以代码演进方式学习LINQ必备条件
今天,我们通过一个简单的示例代码的演进过程,来学习LINQ必备条件:隐式类型局部变量:对象集合初始化器:委托:匿名函数:lambda表达式:扩展方法:匿名类型.废话不多说,我们直接进入主题. 一.实现 ...
- 关于php中数据访问的几点补充
前几篇文章说了,parent.self.static关键字的使用,parent可以访问父类的静态方法和静态变量,self和static可以访问本类的静态成员等等,但实际上他们还有其他作用,来看一下: ...
- .NET 中数据访问用的 DBHelper(Sql Server) 类
public class DBHelper { private static string DBConnectString = "Data Source=.;Initial Catalog= ...
- DriverStudio开发PCI设备DMA数据传输
DriverWizard向导可以创建基本的wDM驱动程序框架,包括总线类型,地址空间,中断源,DMA资源,以及IOCTL(i/o控制代码)的定义等等.详细情况可参看DriverStudio的帮助文档, ...
- SharePoint—用REST方式访问列表
REST的定义与作用 在SharePoint 2010中,基本上有如下几种数据访问方式: 服务器端对象模型 LINQ to SharePoint Web Service 客户端对象模型 ADO.NET ...
- SpringBoot定时任务 - 集成quartz实现定时任务(单实例和分布式两种方式)
最为常用定时任务框架是Quartz,并且Spring也集成了Quartz的框架,Quartz不仅支持单实例方式还支持分布式方式.本文主要介绍Quartz,基础的Quartz的集成案例本,以及实现基于数 ...
- Code First开发系列之管理数据库创建,填充种子数据以及LINQ操作详解
返回<8天掌握EF的Code First开发>总目录 本篇目录 管理数据库创建 管理数据库连接 管理数据库初始化 填充种子数据 LINQ to Entities详解 什么是LINQ to ...
- 8天掌握EF的Code First开发系列之3 管理数据库创建,填充种子数据以及LINQ操作详解
本文出自8天掌握EF的Code First开发系列,经过自己的实践整理出来. 本篇目录 管理数据库创建 管理数据库连接 管理数据库初始化 填充种子数据 LINQ to Entities详解 什么是LI ...
- LINQ浅析
在C# 3.0之前,我们对不同的数据源(数据集合.SQL 数据库.XML 文档等等)进行操作(查询.筛选.投影等等),会使用不同的操作方式. C# 3.0中提出了LINQ(Language Integ ...
随机推荐
- git + tortoisegit安装及配置
1. 下载Git-2.6.3-64-bit.exe 2. 安装Git-2.6.3-64-bit.exe,安装时可全部默认配置(安装路径可选) 3. 下载TortoiseGit-1.8.16.0-64b ...
- video.js支持m3u8格式直播
为什么要使用video.js? 1. PC端浏览器并不支持video直接播放m3u8格式的视频 2. 手机端各式各样的浏览器定制的video界面风格不统一,直接写原生的js控制视频兼容性较差 3. v ...
- 【转】Netty系列之Netty可靠性分析
http://www.infoq.com/cn/articles/netty-reliability 首先,我们要从Netty的主要用途来分析它的可靠性,Netty目前的主流用法有三种: 1) 构建R ...
- 规范 : disable account
前台的cookies在后台会去拿account出来,之后在filter status = disable的 用户在登入使用界面请求一个ajax,这时发现是401没有权限,这通常是admin把用户的ac ...
- Struts2之环境配置
在学习struts2之前,首先我们要明白使用struts2的目的是什么?它能给我们带来什么样的好处? 设计目标 Struts设计的第一目标就是使MVC模式应用于web程序设计.在这儿MVC模式的好处就 ...
- alisql安装步骤
卸载原有自带的Mysql yum remove mysql-libs 安装依赖包 yum install centos-release-scl devtoolset-4-gcc-c++ devto ...
- mfc---ActiveX控件
AvtiveX控件可看做是一个极小的服务器应用程序,不能独立运行,必须嵌入到某个容器程序中 容器应用程序:可以嵌入或链接对象的应用程序 服务器应用程序:创建对象并且当对象被双击时,可以被启动的应用程序 ...
- J2ee技术难点
J2ee技术难点 session/cookie区别联系 jsp/servlet区别联系 filter执行流程 openSessionInView原理 clone与servilizable区别联系 eq ...
- Contains Duplicate leetcode
Given an array of integers, find if the array contains any duplicates. Your function should return t ...
- linux命令分块总结---多操作才是真理
ps:其实学习linux系统,多多联系我们现在使用的Windows系统,这样就可以事半功倍的学习: 一. 启动,关机,登入,登出相关命令 [login]: 登录 [logout] :登出 [shutd ...