.NET中数据访问方式(一):LINQ

简介: 语言集成查询(Language-Integrated Query),简称LINQ,.NET中的LINQ体系如下图所示:   在编程语言层次,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 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>8000
    select e).ToList()

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

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

  • 对于排序、分组、联合查询使用LINQ表达式更为方便
//以排序为例,使用年龄、姓名、邮箱进行排序,
//LINQ表达式中使用逗号分隔排序字段,而扩展方法则需要多次调用相应的扩展方法
var result= from e in Employees
            where e.Age>50 && e.Salary>8000
            orderby e.Age,e.Name,e.Email
            select e;

//等价的扩展方法
var result=Employees
           .Where(e=>e.Age>50 && e.Salary>8000)
           .OrderBy(e=>e.Age)
           .ThenBy(e=>e.Name)
           .ThenBy(e=>e.Email);
  • 扩展方法能够提供比LINQ表达式更复杂的查询
//取第26行到36行范围内的数据
var result=Employees.Skip(25).Take(10);

//使用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

版权声明

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

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

目录
相关文章
|
7月前
mvc.net分页查询案例——DLL数据访问层(HouseDLL.cs)
mvc.net分页查询案例——DLL数据访问层(HouseDLL.cs)
|
7月前
|
SQL 开发框架 .NET
|
7月前
|
XML SQL 开发框架
|
13天前
|
XML 开发框架 .NET
.NET 9 中 LINQ 新增功能实操
.NET 9 中 LINQ 新增功能实操
|
2月前
|
SQL XML 关系型数据库
入门指南:利用NHibernate简化.NET应用程序的数据访问
【10月更文挑战第13天】NHibernate是一个面向.NET的开源对象关系映射(ORM)工具,它提供了从数据库表到应用程序中的对象之间的映射。通过使用NHibernate,开发者可以专注于业务逻辑和领域模型的设计,而无需直接编写复杂的SQL语句来处理数据持久化问题。NHibernate支持多种数据库,并且具有高度的灵活性和可扩展性。
40 2
|
2月前
|
开发框架 .NET 开发工具
.NET 9 中 LINQ 新增的功能
.NET 9 中 LINQ 新增的功能
|
4月前
|
开发框架 .NET 数据库连接
闲话 Asp.Net Core 数据校验(三)EF Core 集成 FluentValidation 校验数据例子
闲话 Asp.Net Core 数据校验(三)EF Core 集成 FluentValidation 校验数据例子
|
5月前
|
开发框架 JSON 前端开发
利用查询条件对象,在Asp.net Web API中实现对业务数据的分页查询处理
利用查询条件对象,在Asp.net Web API中实现对业务数据的分页查询处理
|
4月前
|
开发框架 前端开发 算法
分享 .NET EF6 查询并返回树形结构数据的 2 个思路和具体实现方法
分享 .NET EF6 查询并返回树形结构数据的 2 个思路和具体实现方法
|
7月前
|
存储 测试技术 计算机视觉
高维数据惩罚回归方法:主成分回归PCR、岭回归、lasso、弹性网络elastic net分析基因数据
高维数据惩罚回归方法:主成分回归PCR、岭回归、lasso、弹性网络elastic net分析基因数据