C#学习笔记(九):LINQ和表达式树
LINQ
LINQ:语言集成查询(Language Integrated Query)是一组用于c#和Visual Basic语言的扩展。它允许编写C#或者Visual Basic代码以查询数据库相同的方式操作内存数据。
借助于LINQ技术,我们可以使用一种类似SQL的语法来查询任何形式的数据。目前为止LINQ所支持的数据源有SQL Server、Oracle、XML(标准通用标记语言下的一个应用)以及内存中的数据集合。开发人员也可以使用其提供的扩展框架添加更多的数据源,例如MySQL、Amazon甚至是GoogleDesktop。
起源
.net的设计者在类库中定义了一系列的扩展方法来方便用户操作集合对象,而就是这些扩展方法构成了LINQ的查询操作符。
约束
LINQ的扩展方法都是针对实现IEnumerable接口的对象进行扩展的也就是说,只要实现了IEnumerable接口,就可以使用这些扩展方法。
语法
LINQ查询时有两种语法可供选择:查询表达式(Query Expression)和方法语法(Fluent Syntax)。
.NET公共语言运行库(CLR)并不具有查询表达式的概念。所以,编译器会在程序编译时把查询表达式转换为方法语法,即对扩展方法的调用。所以使用方法语法会让我们更加接近和了解LINQ的实现和本质,并且一些查询只能表示为方法调用。但另一方面,查询表达式通常会比较简单和易读。不管怎样,这两种语法是互相补充和兼容的,我们可以在一个查询中混合使用查询表达式和方法语法。
查询关键字
子句 |
说明 |
---|---|
指定数据源和范围变量(类似于迭代变量)。 |
|
根据一个或多个由逻辑“与”和逻辑“或”运算符(&& 或 ||)分隔的布尔表达式筛选源元素。 |
|
指定当执行查询时返回的序列中的元素将具有的类型和形式。 |
|
按照指定的键值对查询结果进行分组。 |
|
提供一个标识符,它可以充当对 join、group 或 select 子句的结果的引用。 |
|
基于元素类型的默认比较器按升序或降序对查询结果进行排序。 |
|
基于两个指定匹配条件之间的相等比较来联接两个数据源。 |
|
引入一个用于存储查询表达式中的子表达式结果的范围变量。 |
|
join 子句中的上下文关键字。 |
|
join 子句中的上下文关键字。 |
|
join 子句中的上下文关键字。 |
|
group 子句中的上下文关键字。 |
|
orderby 子句中的上下文关键字。 |
|
orderby 子句中的上下文关键字。 |
语法示例
下面提供查询表达式(Query Expression)和方法语法(Fluent Syntax)两种示例,实现的效果是取出数组中的偶数。
using System;
using System.Linq; namespace Study
{
class Program
{
private static void Main(string[] args)
{
//定义数据源
int[] nums = {, , , , , , , , , }; //使用查询表达式
var queryResult1 = from num in nums where num % == select num; foreach (int num in queryResult1)
{
Console.Write("{0,1} ", num);
} Console.WriteLine(); //使用方法语法
var queryResult2 = nums.Where(num => num % == ); foreach (int num in queryResult2)
{
Console.Write("{0,1} ", num);
} Console.Read();
}
}
}
使用LINQ操作XML
在C#3.0之前,使用的是System.Xml.XmlDocument来处理XML数据,操作稍显繁琐,下面我们看一个使用LINQ操作XML数据的例子:
using System;
using System.Linq;
using System.Xml.Linq; namespace Study
{
class Program
{
private static string xmlString =
"<Persons>" +
"<Person Id='1'>" +
"<Name>张三</Name>" +
"<Age>18</Age>" +
"</Person>" +
"<Person Id='2'>" +
"<Name>李四</Name>" +
"<Age>28</Age>" +
"</Person>" +
"<Person Id='3'>" +
"<Name>王五</Name>" +
"<Age>38</Age>" +
"</Person>" +
"</Persons>"; private static void Main(string[] args)
{
XElement xmlDoc = XElement.Parse(xmlString); var queryResult = from element in xmlDoc.Elements("Person")
where element.Element("Name").Value == "李四"
select element; foreach (var xElement in queryResult)
{
Console.WriteLine("姓名: " + xElement.Element("Name").Value + ", Id为: " + xElement.Attribute("Id").Value);
} Console.Read();
}
}
}
LINQ的本质
LINQ在我们看来是添加了新的语法和特性,但其实对于编译器而言并没有添加任何新的东西,编写的LINQ查询语句其实在编译后会转变为编译器可以认识的Lambda表达式和扩展方法。
表达式树
表达式树是将Lambda表达式按树形结构来进行组合的一种数据结构,其主要作用是为了在LINQ中构造动态查询。
好文链接
打造自己的LINQ Provider(上):Expression Tree揭秘
C#学习笔记(九):LINQ和表达式树的更多相关文章
- 多线程学习笔记九之ThreadLocal
目录 多线程学习笔记九之ThreadLocal 简介 类结构 源码分析 ThreadLocalMap set(T value) get() remove() 为什么ThreadLocalMap的键是W ...
- MDX导航结构层次:《Microsoft SQL Server 2008 MDX Step by Step》学习笔记九
<Microsoft SQL Server 2008 MDX Step by Step>学习笔记九:导航结构层次 SQL Server 2008中SQL应用系列及BI笔记系列--目录索 ...
- python3.4学习笔记(九) Python GUI桌面应用开发工具选择
python3.4学习笔记(九) Python GUI桌面应用开发工具选择 Python GUI开发工具选择 - WEB开发者http://www.admin10000.com/document/96 ...
- Go语言学习笔记九: 指针
Go语言学习笔记九: 指针 指针的概念是当时学C语言时了解的.Go语言的指针感觉与C语言的没啥不同. 指针定义与使用 指针变量是保存内存地址的变量.其他变量保存的是数值,而指针变量保存的是内存地址.这 ...
- go微服务框架kratos学习笔记九(kratos 全链路追踪 zipkin)
目录 go微服务框架kratos学习笔记九(kratos 全链路追踪 zipkin) zipkin使用demo 数据持久化 go微服务框架kratos学习笔记九(kratos 全链路追踪 zipkin ...
- C#.NET学习笔记11,12---布尔表达式2组合,if语句
C#.NET学习笔记11---布尔表达式2组合 2013/9/6 技术qq交流群:JavaDream:251572072 教程下载,在线交流:创梦IT社区:www.credream.com int ...
- Python学习笔记九
Python学习笔记之九 为什么要有操作系统 管理硬件,提供接口. 管理调度进程,并且将多个进程对硬件的竞争变得有序. 操作系统发展史 第一代计算机:真空管和穿孔卡片 没有操作系统,所有的程序设计直接 ...
- C#3.0新特性:隐式类型、扩展方法、自动实现属性,对象/集合初始值设定、匿名类型、Lambda,Linq,表达式树、可选参数与命名参数
一.隐式类型var 从 Visual C# 3.0 开始,在方法范围中声明的变量可以具有隐式类型var.隐式类型可以替代任何类型,编译器自动推断类型. 1.var类型的局部变量必须赋予初始值,包括匿名 ...
- C#线程学习笔记九:async & await入门二
一.异步方法返回类型 只能返回3种类型(void.Task和Task<T>). 1.1.void返回类型:调用方法执行异步方法,但又不需要做进一步的交互. class Program { ...
随机推荐
- error: qrc_qml.obj: requires unsupported dynamic reloc R_ARM_REL32; recompile with -fPIC解决办法
使用qtcreator加androidndk编译项目时报错: error: qrc_qml.obj: requires unsupported dynamic reloc R_ARM_REL32; r ...
- django - 好的 获取 参数值 方法
第一步: # 参数列表 parameters = ('user_id', 'day_time', 'normal_data', 'hourly_data', 'product_id') # 需要传入的 ...
- K2 blackpearl 安装
转:http://blog.csdn.net/gxiangzi/article/details/8432188 K2是国外的一款BPM引擎,基于MS的Workflow,关于它的详细介绍在我之前一片博客 ...
- 2.Linq实用性技巧篇
在论坛上经常会看到别人问,linq怎么实现递归,如何求笛卡尔积等问题..都可以用linq快速方便的解决..下面我就来个总的归纳 1.)递归 我们经常会遇到一个情况,就是想获取当前节点下的所有子节点.比 ...
- HDU 5876 Sparse Graph
Sparse Graph Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)To ...
- asp.net如何将DataSet转换成josn并输出
public class JsonUtil { public string ToJson(DataSet dataSet) { string jsonString = "{"; f ...
- BS与CS的联系与区别
C/S是Client/Server的缩写.服务器通常采用高性能的PC.工作站或小型机,并采用大型数据库系统,如Oracle.Sybase.InFORMix或SQL Server.客户端需要安装专用的客 ...
- 初学AngularJS
最近一直想写个网站,所以在做技术准备.在搜索资料的过程中发现了AngularJS,于是顺藤摸瓜找到了一些资料. 学习的最好途径是:上课. 其次是:看录像: ...
- Ubuntu 12.04 中安装ubuntu-tweak出错
错误信息: ubuntu-tweakE: Sub-process /usr/bin/dpkg returned an error code (1) 解决办法: 第一步:删除 /usr/share/py ...
- uva202:循环小数(循环节+抽屉原理)
题意: 给出两个数n,m,0<=n,m<=3000,输出n/m的循环小数表示以及循环节长度. 思路: 设立一个r[]数组记录循环小数,u[]记录每次的count,用于标记,小数计算可用 r ...