Linq 学习笔记(一)
一·前言
Linq 英文全称Language Integrated Query,它提供了C#编程语言中的查询语法,可以使用相同的语法访问不同的数据源。并且Linq还提供了不同数据源的抽象层,所以可以使用相同的语法。本次笔记的主要内容如下:
● 用List<T>在对象上执行传统查询
● 扩展方法
● λ表达式
● LINQ 查询
● 标准查询操作符
● 表达式树
● LINQ 提供程序
一。用List<T>在对象上执行传统查询
首先我们来看一个最简单的例子,请看下面的代码:
List<string> strList = new List<string>();
strList.Add("AAA");
strList.Add("BABB");
strList.Add("ACCC");
strList.Add("BBB");
strList.Add("CCC");
var res = strList.FindAll(delegate(string s) { return s.Contains("A"); });
res.Sort(delegate(string a, string b) { return a.CompareTo(b); });
this.GridView1.DataSource = res;
this.GridView1.DataBind();
这段代码是从strList中查找所有包含字母A的记录,并且将得到的结果进行进行从小到大的排序(如果将return a.CompareTo(b); 换成return b.CompareTo(a);结果则是从大到小的顺序进行排列了)。相信很多人用过这样的方式来对结果集进行过滤和排序操作。但是如果你想在任何集合都可以使用这两个方法,那你就可能会使用到扩展方法了。扩展方法是C#3.0的新增特性,这也是上述例子迈向LINQ 的第一个变化。下面我们就来介绍一下扩展方法。
二。扩展方法
请看下面关于扩展方法的例子
public static class helper
{
public static string MD5Hash(this string s)
{
return System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(s, "MD5");
}
public static bool In(this object o, IEnumerable b)
{
foreach (object obj in b)
{
if (obj == o)
return true;
}
return false;
}
}
// 调用扩展方法
Response.Write("123456".MD5Hash());
Response.Write("1".In(new[]{"1","2","3"}));
上面的例子是对string进行了扩展,这样的话只要在当前命名空间下任何string对象都可以利用该扩展方法。这样会给代码带来很大的方便。
既然有了扩展方法,我们的Linq自然就很容易就出现了。就如同下面的Linq例子一样
MethodInfo[] methods = typeof(string).GetMethods();
var result = from m in methods
where m.IsStatic != true
select m.Name;
foreach (var r in result)
{
Response.Write(r.ToString()+"<br/>");
}
这就是Linq最典型的样子。是不是比较像我们平时用的SQL呢?呵呵虽然还有不小的差别,但是Linq的引入实在是C#的一种革命性的变化。他不仅好用,更给枯燥的C#代码注入了一股鲜活的思想。
三。λ表达式
C# 3.0 给匿名方法提供了一个新的语法——λ表达式(也叫做Lambda表达式)。除了把匿名方法传送给Where()、OrderbyDescen
ding()和Select()方法之外,还可以使用λ表达式。
λ 表达式参见第7 章。λ表达式在LINQ 中非常重要,所以下面复习一下该语法。详细信息可参见第7
章。
比较λ表达式和匿名委托,会发现许多类似之处。λ运算符=>的左边是参数,不需要添加参数类型,因
为它们是由编译器解析的。λ运算符的右边定义了执行代码。在匿名方法中,需要花括号和return 语句。在
λ表达式中,不需要这些语法元素,因为它们是由编译器处理的。如果λ运算符右边有多个语句,也可以使
用花括号和return 语句。
例如下面的例子
var list = new[] { "aa", "bb", "ca" };
var resultList = Array.FindAll(list, s => (s.IndexOf("a") > -1));
foreach (var v in resultList)
Response.Write(v+"<br/>");
s就像是我们在第一个例子中使用的delegate(string s)里面的s一样只是这种使用方法更加的灵活和方便。
四。LINQ 查询
我们就以NorthWind数据库为例,添加一个Linq to Sql Classes命名为Customer.dbml,然后打开Server Explorer设置好连接参数,选择Customers表直接拖拽到Customer.dbml,打开Customer.design.cs文件我们可以看到Visual Studio为我们生成了很多代码。这些代码我们会在后面的内容里详细的讲解。现在主要来讲一下Linq查询以及后面的内容。
LINQ 查询是C#语言中的一个简化查询记号。编译器编译查询表达式,调用扩展方法。查询表达式只是C#中的一个语法,但不需要修改底层的IL 代码。查询表达式必须以from子句开头,以select或group子句结束。在这两个子句之间,可以使用where、orderby、join、let 和其他from子句。注意,变量query只指定了LINQ查询。该查询不是通过这个赋值语句执行的,只要使用foreach循环访问查询,该查询就会执行。
推迟查询的执行
在运行期间定义查询表达式时,查询就不会运行。查询会在迭代数据项时运行。再看看扩展方法Where()。它使用yield return语句返回谓词为true的元素。因为使用了yield return语句,所以编译器会创建一个枚举器,在访问枚举中的项后,就返回它们。
public static IEnumerable<T> Where<T>(this IEnumerable<T> source,Func<T, bool> predicate)
{
foreach (T item in source)
if (predicate(item))
yield return item;
}
请看一下下面的代码
var names = new List<string>{"Nino","Alberto", "Juan", "Mike", "Phil"};
var namesWirhJ = (from name in names where name.StartsWith("J") orderby name select name);
Response.Write("First Iteration<br/>");
foreach (var name in namesWirhJ)
Response.Write(name + "<br/>");
names.Add("John");
names.Add("Jim");
names.Add("Jack");
names.Add("Denny");
Response.Write("Second iteration<br/>");
foreach (var name in namesWirhJ)
Response.Write(name + "<br/>");
其返回结果为
First iteration
Juan
Second iteration
Jack
Jim
John
Juan
但是当我们修改一下代码将 var namesWirhJ = (from name in names where name.StartsWith("J") orderby name select name);换做var namesWirhJ = (from name in names where name.StartsWith("J") orderby name select name).ToList();那么结果就成了
First iteration
Juan
Second iteration
Juan
这就是我们需要注意的地方了,每次在迭代中使用查询时,都会调用扩展方法。在大多数情况下,这是非常有效的,因为我们可以检测出源数据中的变化。但是在一些情况下,这是不可行的。调用扩展方法ToArray()、ToEnu
merable()、ToList()等可以改变这个操作。这也就是为什么我们需要演示ToList()方法了。ToList 迭代集合,返回一个实现了List<string>的集合。之后对返回的列表迭代两次,在这个过程中,数据源被修改了,但是原来的集合并没有改变。这样可以用来实现一些比较复杂的业务逻辑。
五。标准查询操作符
Where、OrderByDescending 和Select 只是LINQ 的几个查询操作符。LINQ 查询为最常用的操作符定
义了一个声明语法。还有许多标准查询操作符。下表列出了Linq的标准查询操作符。
Where OfType<TResult> |
过滤操作符定义了返回元素的条件。在Where 查询操作符中,可以使用谓词, 例如λ表达式定义的谓词,来返回布尔值。OfType<TResult>根据类型过滤元素,只 返回TResult 类型的元素 |
Select和SelectMany |
投射操作符用于把对象转换为另一个类型的对象。Select 和SelectMany 定义 了根据选择器函数选择结果值的投射 |
OrderBy,ThenBy OrderByDescending ThenByDescending Reverse |
排序操作符改变所返回的元素的顺序。OrderBy 按升序排序, OrderByDescending 按降序排序。如果第一次排序的结果很类似,就可以使用 ThenBy 和ThenBy Descending 操作符进行第二次排序。Reverse 反转集合中元 素的顺序 |
Join,GroupJoin |
连接运算符用于合并不直接相关的集合。使用Join 操作符,可以根据键选择 器函数连接两个集合,这类似于SQL 中的JOIN。GroupJoin 操作符连接两个集 合,组合其结果 |
GroupBy |
组合运算符把数据放在组中。GroupBy 操作符组合有公共键的元素 |
Any,All,Contains |
如果元素序列满足指定的条件,量词操作符就返回布尔值。Any,All 和Contains 都是量词操作符。Any 确定集合中是否有满足谓词函数的元素;All 确定集合 中的所有元素是否都满足谓词函数;Contains 检查某个元素是否在集合中。这些操作 符都返回一个布尔值 |
Take,Skip, TakeWhile SkipWhile |
分区操作符返回集合的一个子集。Take、Skip、TakeWhile 和SkipWhile 都是 分区操作符。使用它们可以得到部分结果。使用Take 必须指定要从集合中提 取的元素个数;Skip 跳过指定的元素个数,提取其他元素,TakeWhile 提取条件为真的 元素 |
Distinct,Union Intersect,Except |
Set 操作符返回一个集合。Distinct 从集合中删除重复的元素。除了Distinct 之外,其他Set 操作符都需要两个集合。Union 返回出现在其中一个集合中的 元素。Intersect 返回两个集合中都有的元素。Except 返回只出现在一个集合 中的元素 |
First FirstOrDefault Last LastOrDefault ElementAt ElementAtOrDefault Single SingleOrDefault |
这些元素操作符仅返回一个元素。First 返回第一个满足条件的元素。 FirstOrDefault 类似于First,但如果没有找到满足条件的元素,就返回类型 的默认值。Last 返回最后一个满足条件的元素。ElementAt 指定了要返回的元 素的位置。Single 只返回一个满足条件的元素。如果有多个元素都满足条件, 就抛出一个异常 |
Count,Sum,Min, Max,Average, Aggregate |
合计操作符计算集合的一个值。利用这些合计操作符,可以计算所有值的总和、 元素的个数、值最大和最小的元素,平均值等 |
ToArray ToEnumerable ToList ToDictionary toType<T> |
这些转换操作符将集合转换为数组、IEnumerable、IList、IDictionary 等 |
Empty,Range, Repeat |
这些生成操作符返回一个新集合。使用Empty,集合是空的,Range 返回一系列数 字,Repeat 返回一个始终重复一个值的集合 |
注:本文内容摘自http://blog.sina.com.cn/s/blog_5df2629a0100lr3u.html
ASP.NET开发技术交流群: 67511751(人员招募中...)
转载于:https://www.cnblogs.com/Juvy/archive/2011/08/31/2160845.html
Linq 学习笔记(一)相关推荐
- Linq 学习笔记(二)
Linq 学习笔记(二) 下面就来介绍一些查询的示例: 1.Linq查询 var racers = from r in Formula1.GetChampions() where r.Wins > ...
- 一起谈.NET技术,Linq学习笔记
写在前面 其实在09年就已经学习过Linq了,并被她那优美的语法所吸引,只是现在所在的公司还在使用VS2005在.Net2.0的框架下面的开发,所以Linq也很久没有用过了,最近看部门的同事对这个有些 ...
- linq学习笔记(2):DataContext
在前面学习了C#3.0新语特性和改进,这些新特性在我们编写程序时为我们提供了非常大的帮助.从现在开始正式学习LINQ. LINQ是Language Integrated Query的简 ...
- C# LINQ学习笔记四:LINQ to OBJECT之操作文件目录
本笔记摘抄自:https://www.cnblogs.com/liqingwen/p/5816051.html,记录一下学习过程以备后续查用. 许多文件系统操作实质上是查询,因此非常适合使用LINQ方 ...
- LINQ学习笔记之四:查询内存对象
附上WORD文档,从这里下载. 查询内存对象 这一章中主要介绍了使用LINQ查询内存对象的一些基本语法.在下一章将会有更高级的用法介绍.本章中的示例数据是一个简单的出版社信息.这里是数据文件.下面的图 ...
- Linq学习笔记(三)
下面的代码演示了如何利用Linq结合AspNetPager控件实现分页功能,以及如果利用Linq to Xml将当前页数据保存为Xml using (NorthWindDataContext db ...
- LINQ学习笔记(9) LINQ to Objects---查询内存中对象的集合
从这一篇开始要总结的是LINQ在实际中的应用,首先要总结的是LINQ to Objects,也就是LINQ与程序对象的配合使用. 其中程序对象集合最典型就是与数组的配合使用,如下示例: 1 class ...
- [导入]Linq学习笔记(2.2)——深入DLinq查询
摘要: 深入学习Dlinq对关系型数据库映射对象的查询操作 阅读全文 Young.J 2007-06-10 18:35 发表评论 [小组] [博问] [闪存] 文章来源:http://www.c ...
- linq学习笔记(1):c#3.0新特性(2)
4. Object and Collection Initializers(对象和集合初始器) Object Initializer(对象初始器),顾名思义就是一种初始化对象 ...
- linq学习笔记(5):Count/Sum/Min/Max/Avg
Count/Sum/Min/Max/Avg用于统计数据,比如统计一些数据的个数,求和,最小值,最大值,平均数. 1.Count:返回集合中的元素个数,返回INT类型:不延迟.生成SQL语句为:SELE ...
最新文章
- 会话管理-2.1.Session介绍
- GAN生成对抗网络-PIX2PIXGAN原理与基本实现-图像翻译09
- sql server2008系统表详细说明sys.开头的表
- JS中数据类型、内置对象、包装类型对象、typeof关系
- Spark _03RDD_Transformations_Action_使用scalajavaAPI
- 微软2008系列 (Orcas + Longhorn Server+SQL2008)将于2008年2月27日发布
- 对象工厂PHP,php – 域对象工厂是什么样的?
- 一个好的web前端开发者,是怎么学习的?
- 如何查看有没有django及版本
- oracle操作字符串:拼接、替换、截取、查找、长度、判断
- 一个四维混沌吸引子曲线(matlab完整代码)
- [区块链]区块链技术在殡葬行业的思考
- 电脑计算机窗口不见了怎么调出来,电脑桌面上的任务栏不见了怎么办
- 秋雨,在迷乱的思绪中飞扬
- TCP/IP高频考点之一个数据包的流浪日记 - 网络层
- java 获取当年_java获取当年第一天
- 创业明星|她曾是中国互联网界最年轻的首席运营官:不靠美貌一样征服
- [excel]删除excel中隐藏的双引号(用的WPS)
- 区块链界的微信BTchat链语横空出世,它是什么鬼?
- FFmpeg实现视频倒放: reverse/areverse滤镜