什么是Linq?它是用来做什么的?怎么用?

Linq的优点是不管数据源是什么,都可以统一查询.换言之,它是一种包含一套标准查询操作符的查询语言,可以对多个数据源进行查询

⑴Linq俗称语言集成查询(Language Integrated Query)是一系列标准查询操作符的集合,这些操作符几乎对每一种数据源的导航,过滤和执行操作都提供了低层的基本查询架构.Linq可查询的数据源包括XML,关系数据库,ADO.NET DATASETS,以及内存中的数据,前三者就是熟悉的LINQ TO XML,LINQ TO SQL,LINQ TO DATASET.
语言集成查询意味着将标准查询功能直接整合到了供开发人员选择的基于.NET的编译语言中.这些查询功能,即标准查询操作符,描述了可以应用到多种信息源上的通用查询机制,如在内存构造中的数据,或者从外部数据源(如关系数据库或XML)检索到的数据.
简而言之,LINQ使我们可以查询任何实现了IEnumerable接口的对象.如果可以通过foreach语句循环访问所有内容,那么也就可以使用LINQ对它进行查询

①使用一种简化的方式编写查询语句
②通过消除运行时错误和捕捉编译时错误减少开发时间.
③直接在开发语言中提供对LINQ的IntelliSense和调试支持.
④消除关系数据和面向对象开发之间的障碍.
⑤提供与数据源无关的统一查询语法
需要注意的一个重要方面是,查询系统进程与查询SQL数据源所使用的是相同的语法.
LINQ包括两个标准查询操作符集合,一个集合用于操作IEnumerable类型的对象,另一个用于IQueryable类型的对象(linq to sql).附:尽管linq to sql 没有自己的标准查询操作符实现,它仍被认为是LINQ PROVIDER.因为作为IQueryable接口的一个实现,LINQ TO SQL实现了标准查询操作符处理关系数据库的功能这些操作符由IEnumerable和Queryable类中的静态方法组成.因此它们可以使用实例方法语法的静态方法语法进行调用.可以根据标准查询操作符的操作"类型"对它们进行分类.例如,可以将其分为聚合,投影,排序和分组操作等.
var val=from fn in firstnames where fn.Startswith("S") select fn.
⒈select属于投影操作符它,在某个序列(实现了IEnumerable接口)上进行投影.在此,select操作符将枚举由名字构成的序列源
⒉where属于限制操作符类型,事实上,它是该类型唯一的操作符.类似T-SQL,LINQ中的where操作符过滤某个序列.
LINQ 利用了SQL架构产生的信息,并将这些信息直接整合到使用CLR的元数据中.正因为存在此集成,所以能够将SQL中表和视图的定义编译为CLR类型,从而可以用编程语言直接对其进行访问

接下来,将逐步解释LINQ查询的各个组成部分,并演示如何将它们组合在一起并执行.一个LINQ查询操作包含以下三个不同的,独立的动作:
⑴获取数据源
⑵创建查询
⑶执行查询
每个动作都是创建和执行LINQ查询必不可少的
⑴获取数据源
LINQ的强大之处在于它并不关心要查询的数据源是什么.但是成为数据源的关键是必须支持IEumerable接口
⑵创建查询
定义了数据源之后,下一步是定义查询来确定要从数据源中检索的数据或信息.也可以指定返回的组织方式,如排序或分组.说白了就是写查询语法
⑶执行查询
查询执行分为两种类型:一种是延迟执行和立即执行.在大多数情况下都会使用延迟执行,但也存在需要使用立即执行的情况
1.延迟执行
只有当开始循环访问查询变量时这种查询才会执行,如使用foreach循环.延迟执行适用于返回一个序列(多个值)的情况.因为查询(和变量)不包含查询结果,我们可以以较小的开销自由地多次执行(遍历)这个查询
2.立即执行
任何返回单个值的LINQ查询都会被立即执行.返回类似于COUNT或MAX的查询的结果可认为是单个值.也可以通过调用ToList或者ToArray方法来强制查询立即执行.当希望对查询的结果进行缓存时这种做法很有用.

然后让我们来了解一下,SQL SERVER是如何执行这些查询的?记住,SQL是按照以下顺序以一定的逻辑处理查询的
FROM,ON,JOIN,WHERE,GROUP BY,WITH,HAVING,SELECT,TOP,ORDER BY

查询的概念

实战来看. select c in contact where c.FirstName.StartsWith("S") orderby c.LastName select c
在这实例中,第一个子句是from,它指定了数据的来源.它被称为生成器,定义了数据来自何处以及查询在何处执行.它也为数据源中的每个元素指定了一个范围变量,用来作为参考.在一下示例中,contact是数据源并且c是范围变量:
from c in contact
where子句可以对查询返回的结果进行过滤.通过把过滤应用到查询中,不仅可以限制返回行的数目,还可以从返回结果中指定希望看到或排除掉的行.例如,下面将返回那些以S字母开头的联系人:where c.FirstName.Startswith("S"),如果要有多个过滤规则,在c#中额可以像sql中一样加连字符.sql中是and/or,linq中是&&/||.另外orderby 是可选的,默认按升序,如果要降序,则使用descending结尾即可.补充一点,也可以进行多个排序order BY c.lastName,c.FirstName同sql一样,也可以按照查询的属性之一结果进行分组.例如group c by c.Country.
最后一步是使用select子句将数据进行投影(选择).通过投影数据,可以将结果定义为其他失事物而不是原有数据的简单的副本.例如:如果数据源返回FirstName,LastName,EmailAddress,Title,MiddleName和City,但select子句只使用结果中的FirstName和LastName,这就是一个投影.
连接操作:from c in contact join c in orders on c equals o.OrderID where c.FirstName.StartWith("S") order by c.FirstName select new {c.FirstName,c.LastName,c.EmailAddress,o.OrderDate}

var与IEnumberable比较

关键字var是c#3.0中的新增内容,它使您能够在方法的范围内隐式地声明变量.它的强大之处在于,隐式的类型变化具有同其对应的显式声明的变量一样的强类型.
.net framework2.0中新增的IEnumerable接口,支持在一个特定类型的元素集合中进行简单的遍历.它给出了IEmunerable接口,这是所有的范型枚举器的基本接口

查询语法和方法语法的区别:
查询语法:IEnumerable query=from c in contact where c.FirstName.StartsWith("S") select c; (和SQL查询一样)
方法语法:IEnumerable query=contact.where(c=>c.FirstName.Startwith("S")); (条件都在括号里.和方法使用一样)
建议尽量使用查询语法,因为它更容易阅读,理解和维护.但是也有很多原因导致不使用查询语法
⑴在查询语法中并非所有的标准查询操作符都能使用.
⑵在查询语法中并非所有的标准查询操作符组合都能使用.
⑶在后面可以了解到,可以把查询语法与方法语法结合起来,但有时候直接使用方法语法可能会使程序的可读性更强.

LINQ标准查询操作符

标准查询操作符是LINQ查询表达式的构成模块,它们提供了许多查询功能,如过滤和排序.标准查询操作符是构成查询模式的一系列方法的集合,并通过各自的LINQ提供程序来实现如LINQ TO XML和LINQ TO DATASETS.正如前面所说,标准查询操作符是一系列方法的集合.这些方法作用于序列之上.序列是一个实现了IEnumerable接口或IQueryable接口的类型的对象.IEnumerable接口提供了遍历特定类型集合的功能.IQueryable接口提供了一个在数据类型已知的某个已知的,特定数据源上执行查询的功能.这就是意味着,通过IQueryable接口和IQueryable接口可以得到一个能够执行查询的对象.IQueryable接口是基于表达式的.两者区别:IEnumerable接口提供了向前遍历的功能.它不具有在各个数据项之间移动(向前移动除外)的能力.然而,IQueryable可以使查询操作更具灵活性.虽然是后者继承前者,但不要忘记后者继承了前者的遍历特性.
有两种类型的操作符,一种作用在IEnumerable对象之上,一种作用在IQueryable对象之上,每张操作符都是作为其相应类型的静态方法来实现的,这意味着操作符可使用静态方法语法调用,也可以使用实例方法调用.

下面一一来介绍查询操作符:

投影操作符(select 和selectMany)
投影是指将序列中的元素转换为一个由开发人员定义的的操作.投影操作符Select和SelectMany用于选择赋予了适当功能的值.尽管二者都可以选择值,但是SelectMany操作符可以处理多个集合.
举例
语法查询:var query=from c in contact where c.FirstName.StartsWith("S") select new {c.FirstName,c.LastName}
方法查询:var query=contact.where(c=>new {c.FirstName,c.LastName}).where(c.startsWith("S"));注意,在编译时,语法查询都将转换为方法查询
selectMany可以处理集合中的集合,提供了将多个from子句组合起来的功能,它将每个对象的结果合并成单个序列:foreach(var item in query.SelectMany(m=>m.pets))
限制操作符(where)
排序操作符(OrderBy,OrderByDescending,ThenBy,ThenByDescending和Reverse),提供了按照升序或降序的方式对结果进行排序的功能.多种排序选择让您可以实现按照主关键字和按照次关键字排序.排序要在select之前使用
其中thenBy操作符实现按照次关键字对序列进行升序排序.这类似于在T-SQL中使用次要排序顺序,如sql中的 order by t.name,t.age中的t.age用法是先orderby t.name thenby t.age. Reverse操作符不会根据每个值来决定排序顺序,它只是简单地把数据源中的数据按照相反(逆向)的顺序返回.即反序排列,好像没多大的意义.
连接操作符
联接是指一个数据源对象与另一个数据源对象进行关联或联合操作.这两个数据源对象通过一个共同的值或属性进行关联.Linq的联接操作符包含可匹配(或相同)关键字的两个或多个数据源中的值进行匹配.LINQ有两个联接操作符:join和groupjoin.
1.join
join操作符类似于T-SQL中的inner join,后者将一个数据源与另一个数据源相联接,根据两个数据源中相等的值进行匹配.当然也可以使用多个数据源,查询方法如下:
var query=contact.join(employee,con=>con.ContactID,emp=>emp.ContactID,(con,emp)=>new {Contact=con.FirstName,Employee});
2.Group join
此操作符将主要数据源(第一个或左边的)中的每一个值或元素与次数据源(右边的)中相应的值联接起来.这种类型的联接在需要建立层次式数据结构时十分方便.如下将赛车队与各个赛车队的队员连接其来.用法与join一样
var teamsandriders=teams.GroupJoin(riders,Team=>Team.name,Rider=>Rider.TeamName,(Team,TeamRiders)=>new {Team=team.name,riders=teamRiders.Select(rider=>rider.name)});
3.分组操作符
分组是指根据一个特定的值(选择器)将序列中的值或元素进行分组.Linq只包含一个分组操作符:GroupBy.例如
var query=(from o in orders where o.SalesPersonID>0 select o).GroupBy(order=>order.SalesPersonID,order=>CustomerID);注意此查询同时使用了查询语法和方法语法,同时还因为GroupBy在查询语法中不能使用
4.串联操作符
串联是一个将两个对象联接在一起的过程.在LINQ中,串联操作将两个集合合并成一个集合,这通过Concat操作符实现.
5.聚合操作符
聚合函数在一系列的值上执行特定的运算,并返回这个值,如在给定元素的值执行行求和或计数运算.共有7种LINQ聚合查询操作符:Aggregate,Average,Count,LongCount,Max,Min和Sum.
Aggregate操作符从某一特定列或集合中收集值.当聚合完成时它将序列中返回的值进行累积并返回结果.
6.集合操作符
集合操作符对元素的集合或序列集合进行操作,并返回一个集合.共有4种LINQ集合查询操作符:Distinct,Union,Intersect和Except.
⑴Distinct
Distinct操作符删除集合中重复的值,并返回集合中互不相同的元素.例如numbers是一个字符串数组,numbers.Distinct()就会剔除集合中相同的元素
Union操作符返回两个序列或集合中的每个互不相同的元素.与contact操作符不同,Union操作符返回互不相同的元素,而contact操作符将返回所有的值.numbers1和numbers2两个结果集,numbers1.Union(numbers2)将返回两个结果集中不重复的值
Intersect操作符将返回两个序列的交集.也就是返回那些同时存在于两个序列或集合中的值.
Except操作符与Intersect操作符相反,它返回两个序列中不同的部分,也就是说,它将返回序列中所有的独特(不重复)的值(出现在第一个序列中但不会出现在第二个序列中).换言之,它是指"序列A有而序列B中没有的元素".
7.生成操作符
1.Empty
例如:Enmerable.Empty()就是一个空集合

)此示例中,第一次遍历时,current就是一个空集合.然后与其他集合对比,结果就淘汰了第一个集合.同理可以用此来筛选出你想要的集合
2.Range
Range操作符用来创建一个包含数字序列的集合,它包含两个参数,第一个参数是作为序列的开始的整数值,第二个参数是要产生的整数序列数字的个数.
3.Repeat
Repeat操作符创建一个单值序列,将此值重复一定的次数.

8.转换操作符
转换是指将输入对象的类型转变为序列的动作.转换操作符用于实现此类功能
㈠AsEnumerable
它是指将查询的输入以IEnumerable(OfT)类型返回,这意味着可以将数据的类型从实现IEnumerable(OfT)的类型转换为IEnumerable(OfT)类型本身.
㈡Cast
Cast操作符将IEnumerable集合中的元素转换为某种指定的类型.这样做的好处是通过提供必要的类型信息,可以将标准查询操作符应用于非范型集合之上.
㈢OfType
OfType操作符能够实现基于一个特定的类型IEnumerable对象的元素进行过滤.
㈣ToArray
ToArray操作符用于实现从一个IEumerable序列创建一个数组.
㈤ToDictionary
ToDictionary操作符将序列中的所有返回元素插入到一个Dictionary(Of TKey,TValue)对象中,下面的示例中使用

㈥ToList
ToList操作符将一个IEnumerable序列集合转换一个List(Of T)对象.它也会强调查询立即执行.
㈦ToLookup
ToLookup操作符基于一个特定的主键,将返回的元素放置到一个Lookup(Of Tkey,TElement)对象中.Lookup是主键的集合,其中每个主键都映射到一个或多个值上.可以认为Lookup对象是一个一对多的字典.
9.元素操作符
元素操作符从一个序列返回单个特定的元素.
①DefaultEmpty
DefaultEmpty操作符将一个空集合替换为包含默认的单个值的集合.在返回序列为空且又需要返回一些对象时,可以通过该操作符返回一个默认值.

如果集合中的话,就会返回none
②ElementAt
ElementAt操作符返回集合中给定索引处的元素.集合是零基(索引从0开始计)的,返回值是数据源中特定位置的元素.
③ElementAtOrDefault
它将ElmentAt操作符和DefaultEmpty操作符的部分功能结合在了一起,返回在某一特定索引处的元素,或者是,如果索引超出范围则返回默认值.
④First
顾名思义,First操作符返回集合中的第一元素.下面的示例查询Contact表来寻找所有名字以字母S开头的联系人.First操作符返回结果集合中的第一个元素.如果数据眼有可能为空,则使用FirstOrDefault操作符.First(name=>name.Lenght>5)还可以增加匿名函数在里面.
⑤Last
与First操作符相反,Last操作符返回集合中的最后一个元素.下面的代码查询Contact表,寻找所有名字以字母S开头的联系人,Last操作符返回结果集合中的最后一个元素:
⑥FirstOrDefault
FirstOrDefault操作符返回集合中的第一个元素,或者,如果没有发现任何元素则返回默认值.下面的示例通过查询Contact表来寻找所有名字以字母ZZ开头的联系人,并用FirstOrDefault操作符返回结果中的第一个元素.如果没有发现满足条件的元素,将返回默认值.默认值被定义为第一个满足条件查询的元素.
⑦LastOrDefault
LastOrDefault操作符返回集合中的最后一个元素,或者是,如果没有找到任何元素则返回一个默认值.下面的示例通过查询Contact表,查询所有名字以ZZ开头的联系人.它使用LastOrDefault操作符返回集合中的最后一个元素.如果没有找到满足条件的元素,则返回默认值.
⑧Single
Single操作符从一个序列中返回单个元素,或唯一满足某一特定条件的元素.如果您知道查询将返回单个元素,就可以使用这个操作符.如果序列返回多个元素而又使用了此操作符,则会抛出异常.
⑨SingleOrDefault
与Single操作符类似,SingleOrDefault操作符从一个序列中返回单个元素,但如果没有发现元素它也会返回一个默认值.再次注意,仅当我们知道查询将返回单个元素或返回空元素的时候才可以使用此操作符.如果使用了SingleOrDefault操作符而序列又返回了多个元素,就会抛出异常.
10.相等操作符
相等操作符通过比较两个序列来检查它们相应的元素是否相同.如果两个序列有相同数量的元素,并且对应元素的值相同,则认为这两个序列是相等的.
SequeneEqual操作符判定两个集合是否相等.判定是通过并行地枚举两数据源并比较相应元素来完成的.返回值是一个Boolean值--如果两个集合相等则返回ture,否则返回false.
11.量词操作符
量词操作符返回一个Boolean值,指示序列中是否存在部分或全部元素符合某个特定条件.
⑴All
All操作符判定在集合中是否所有的值都满足特定的条件.返回值是一个boolean值,如果所有值都满足条件则返回true,否则返回false.
举例来说,下面的代码定义了一个名字数组并且应用了All操作符,所指定的条件是所有的名字以字母J开头.
㈡Any
Any操作符判定一个集合中是否有任何满足条件的值,或者一个序列中是否包含有满足特定条件的元素.返回结果是一个Boolean值--如果存在至少一个值满足条件则返回true,否则返回false.
㈢Contains操作符判定返回的集合是否包含某个特定的元素.返回值是一个Boolean值----如果存在满足条件的元素则是返回true,否者返回false.
12.分隔操作符
分隔是指将一个单一的输入序列划分成两个或多个部分或序列,同时不会对输入元素重排序,然后返回一个新形成的部分.分隔符包括Skip,SkipWhile,Take,TakeWhile.
①Skip
Skip操作符会跳过一些元素到达序列中一个特定的位置.换句话说,它将略过特定数目的若干元素并且返回其余的元素.
下面的示例中定义了一个随机的数字集合,将它们按升序排序,然后使用Skip操作符跳过前4个数字并返回剩余部分的数字
IEnumnerable skipLowerFour=(from n in randomNumbers order by n select n).skip(4)
②skipWhile
SkipWhile操作符基于特定的谓词逻辑跳过或略过元素,并且只要特定的条件为真(即条件没被满足)就继续略过元素,然后返回余下的元素.例如
IEnumnerable skipLowerFour=(from n in randomNumbers order by n select n).skipWhile(num=>num<50)
③Take
Take操作符返回某个序列中连续的元素子序列,子序列开始于原序列的开头,结束于某个指定的位置.意思就是取前几个数字
IEnumnerable takeTopFour=(from n in randomNumbers order by n descending select n).Take(4)
④TakeWhile
TakeWhile操作符基于特定的谓词逻辑返回元素,并且只要指定的条件为真(即条件没有不被满足)就继续选取元素.否则其余元素将会被跳过.

Linq世界走一走的更多相关文章

  1. (DIjsktra算法) nyoj1401-一场说走就走的旅行

    题目描述: 有一天,孩子回来对我说:“妈妈,听说马尔代夫很不错,放假了我想去玩.”马尔代夫?我也想去!没有人不向往一场说走就走的旅行!“其实我想去的地方很多,呼伦贝尔大草原.玉龙雪山.布达拉宫.艾菲尔 ...

  2. Python带你来一次说走就走的环球旅行

      image 1.目 标 场 景 十一长假,相信大部分的朋友这会应该是在全国各地浪或者是在浪的路上,朋友圈成为你们表演的场所. 当然,也有一小戳朋友是选择家里蹲,你们是否感觉到无聊?是否想出去浪,参 ...

  3. linq世界走一走(LINQ TO SQL)

    前言:作为linq的一个组件,同时作为ADO.NET的一个组成部分,LINQ TO SQL提供了将关系数据映射为对象的运行时基础结构. LINQ TO SQL是通过将关系数据库对象的数据模型(如一个数 ...

  4. Linq世界走一走(LINQ TO XML)

    前言:Linq to xml是一种使用XML的新方法.从本质上来说,它采用了多种当前使用的XML处理技术,如DOM和XPath,并直接在.NET Framework内将它们组合为一个单一的编程接口.L ...

  5. 来一场说走就走的骑行---23KM的上班探路行动圆满结束

    上午带着宝贝在游乐场疯了2小时,回家吃过中午饭,收拾利落,刚上刚拾掇利落的单车,出发,目的地:公司.预测距离22.5KM目的    1 锻炼身体,变每天上下班的娱乐时间为锻炼时间.    2 省钱(其 ...

  6. 做高逼格程序员之说走就走的「Linux To Go 」

    简介:想拥有一个Linux,在自己的电脑上安装双系统太麻烦.想和WTG一样,随插随用. 使用LTG的好处 安装.修复系统:配置好后的Linux系统极其强大. 工作中我们同样可以使用这个系统,回到家里插 ...

  7. 旅行,说走就走 Help? [C++数据类型和表达式]

    摘要: 原创出处: http://www.cnblogs.com/Alandre/ 泥沙砖瓦浆木匠 希望转载,保留摘要,谢谢! 乐天派.我却喜欢和老妈说"老妈小时候喜欢羡慕别人有动力,现在看 ...

  8. 做高逼格程序员之说走就走的「Windows」

    简介:随着移动固态硬盘越来越便宜,网上逐渐出来一个黑科技.Windows To GO见名知意.简单来说就是在U盘或者是移动固态硬盘上安装Windows系统.达到即插即用. WTG 简介 Windows ...

  9. AD走圆弧走线

    美式键盘: “shift  +  空格”

随机推荐

  1. chrome developer tool 调试技巧

    这篇文章是根据目前 chrome 稳定版(19.0.1084.52 m)写的, 因为 google 也在不断完善chrome developer tool, 所以 chrome 版本不同可能稍有差别. ...

  2. html5中manifest特性测试

    测试环境和工具   chromium  18.0.1025.151 (开发编译版 130497 Linux) Ubuntu 11.04 一.测试内容 1.A页面manifest缓存的js文件,B页面不 ...

  3. 在Windows8 Winrt中 高性能处理多个条件语句 用于实现自定义手势

    http://blog.csdn.net/wangrenzhu2011/article/details/8578806 (转) 在winrt中 多点触控 控件的应用越来越多,例如 各种手势与 控件之间 ...

  4. Codeforces Round #204 (Div. 2) A.Jeff and Digits

    因为数字只含有5或0,如果要被90整除的话必须含有0,否则输出-1 如果含有0的话,就只需考虑组合的数字之和是9的倍数,只需要看最大的5的个数能否被9整数 #include <iostream& ...

  5. TYVJ 1011 NOIP 2008&&NOIP 2000 传纸条&&方格取数 Label:多线程dp

    做题记录:2016-08-15 15:47:07 背景 NOIP2008复赛提高组第三题 描述 小渊和小轩是好朋友也是同班同学,他们在一起总有谈不完的话题.一次素质拓展活动中,班上同学安排做成一个m行 ...

  6. 【UR #4】元旦三侠的游戏(博弈论+记忆化)

    http://uoj.ac/contest/6/problem/51 题意:给m($m \le 10^5$)个询问,每次给出$a, b(a^b \le n, n \le 10^9)$,对于每一组$a, ...

  7. Odoo ir actions 分析

    源代码位置:openerp/addons/base/ir/ir_actions.py 根类型:ir.actions.actions class actions(osv.osv): _name = 'i ...

  8. 使用LTT升级HP磁带机的固件程序

    下载后将软件包解压 解压后,进入该文件夹可以看到固件程序     将所有固件程序拷贝至LTT软件安装目录下的firmware文件夹中 C:\Program Files\HP StorageWorks ...

  9. MyEclipse的注册过程

    说在前面的话: 说到收费软件MyEclipse,大家可能对它又爱又恨,其实软件收钱也是为了有更好的发展,我们的建议是先试用,如果觉得不错,可以使用正版软件! 准备工作: 1.MyEclipse安装文件 ...

  10. Web中的图标

    随着时代的变迁与技术的不断的更新,在当今这个时代,Web中的图标(Icons)不再仅仅是局限于<img>.除了<img>直接调用Icons文件之外,还有Sprites(俗称雪碧 ...