LINQ to SQL.doc_第1页
LINQ to SQL.doc_第2页
LINQ to SQL.doc_第3页
LINQ to SQL.doc_第4页
LINQ to SQL.doc_第5页
免费预览已结束,剩余102页可下载查看

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

LINQ查询的目的是从指定的数据源中查询满足符合特定条件的数据元素,并且通过根据需要对这些查询的元素进行排序、连接等操作。所以LINQ查询包含如下几个主要元素: 数 据源:数据源表示LINQ查询将从哪里查找数据,它通常是一个或多个数据集,每个数据集包含一系列的元素。数据集是一个类型为 IEnumerable或IQueryable的对象,可以对它进行枚举,遍历每一个元素。此外,它的元素可以是任 何数据类型,所以可以表示任何数据的集合。 目标数据:数据源中的元素并不定是查询所需要的结果。目标数据用来指定查询的具体想要的是什么数据。在LINQ中,它定义了查询结果数据集中元素的具体类型。 筛选条件:筛选条件定义了对数据源中元素的过滤条件。只有满足条件的元素才作为查询结果返回。筛选条件可以是简单的逻辑表达式表示,也可以用具有复杂逻辑的函数来表示。 附加操作:附加操作表示一些其它的具体操作。比如,对查询结果进行分组等。其中,数据源和目标数据库是LINQ查询的必备元素,筛选条件和附加操作是可选元素。1.查询表达式关键字关键字功能from指定要查找的数据源以及范围变量,多个from子句则表示从多个数据源查找数据select指定查询要返回的目标数据,可以指定任何类型,甚至是匿名类型where指定元素的筛选条件,多个where子句则表示了并列条件,必须全部都满足才能入选orderby指定元素的排序字段和排序方式。当有多个排序字段时,由字段顺序确定主次关系,可指定升序和降序两种排序方式group指定元素的分组字段join指定多个数据源的关联方式2.用from子句指定数据源每个LINQ查询都以from子句开始,from子句包括以下两个功能。 指定查询将采用数据源。 定义一个本地变量,表示数据源中单个元素。单个from子句的编写格式如下所示。其中dataSource表示数据源,localVar表示单个元素。from localVar in dataSource3.用select子句指定目标数据select子句指定在执行查询时产生结果的数据集中元素的类型,它的格式如下所示:select element4.用where子句指定筛选条件在LINQ中,用where子句指定查询的过滤条件,它的格式如下:where expression其中,express是一个逻辑表达式,返回布尔值“真”或“假”在LINQ查询中,还可以使用多个并列的where子句来进行多个条件过滤。数据源中的元素只有同时满足所有where子句的条件才能作为查询结果。5.用orderby子句进行排序在LINQ中,通过orderby子句对查询结果进行排序操作,它的格式如下:orderby element sortType其中,element是要进行排序的字段,它可以是数据源中的元素,也可以是对元素的操作结果。sortType是可选参数,表示排序类型,包括升序(ascending)和降序(desending)两个可选值,默认情况下为ascending。注意:orderby子句和where子句不一样,当在一个LINQ查询中出现多个orderby子句时,只有最后一个orderby子句有效,前面的orderby子句都无效。6.用group子句进行分组在LINQ中,用group子句实现对查询结果的分组操作。在LINQ中,group子句的常用格式如下:group element by key其 中,element表示作为查询结果返回的元素,key表示分组条件,。group子句返回类型为 IGrouping的查询结果。其中,TKey的类型为参数key的数据类型,TElement的类型是参数 element的数据类型。有时需要对分组的结果进行排序,再次查询等操作。这就需要使用into关键字将group查询的结果保存到一个临时变 量,并且必须使用新的select或group子句对其进行重新查询,也可以使用orderby进行排序、用where进行过滤等操作。into关键字的 语法格式如下:group element by key into tmpGrp其中tmpGrp表示一个本地变量,用来临时保存group产生的结果,提供后面的LINQ子句使用。1.用from子句进行复核查询using System;using System.Linq;namespace ConsoleApplication1 class Program static void Main(string args) int intAry1 = 2,3,4,5,6,77; int intAry2 = 2,4,4,345,45,34,23,324,243,423,213343; var query1 = from var1 in intAry1 from var2 in intAry2 where var1 % var2 = 0 group var2 by var2; foreach (var grp in query1) Console.WriteLine(0, grp.Key); foreach (var item in grp) Console.WriteLine(0,item); Console.WriteLine(); 2.用join子句进行内部联接内部联接中join子句的格式如下所示:join element in dataSource on exp1 equals exp2其 中,dataSource表示数据源,它是联接要使用的第二个数据集。element表示存储dataSource中元素的本地变量。exp1和exp2 表示两个表达式,它们具有相同的数据类型,可以用equals进行比较。如果exp1和exp2相等,则当前的元素将添加到查询结果。using System;using System.Linq;namespace ConsoleApplication2 class Program static void Main(string args) int intAry1 = 5, 15, 25, 30,40,50,60,70, ; int intAry2 = 10, 20, 30, 40, 50, 60 ; var query1 = from val1 in intAry1 join val2 in intAry2 on val1 equals val2 select new Val1 = val1, Val2 = val2 ; foreach (var item in query1) Console.WriteLine(item); 3.用join子句进行分组联接有时候需要将查询结果按照第一个数据集中的元素进行分组,这就需要使用join子句的另外一种用法-分组联接。join element in dataSource on exp1 equals exp2 into grpName其中,into关键字表示将这些数据分组并保存到grpName中,grpName是保存一组数据的集合。using System;using System.Linq;namespace ConsoleApplication2 class Program static void Main(string args) int intAry1 = 5, 15, 25, 30,40,50,60,70, ; int intAry2 = 10, 20, 30, 40, 50, 60 ; var query1 = from val1 in intAry1 join val2 in intAry2 on val1 equals val2 into valGrp select new Val1 = val1, Val2 = valGrp ; foreach (var obj in query1) Console.WriteLine(0,obj.Val1); foreach (var item in obj.Val2) Console.WriteLine(0, item); Console.WriteLine(); 4.用join子句进行左外部联接第三种联接是左外部联接,它返回第一个集合中的所有元素,无论它是否在第二个集合中有相关元素。在LINQ中,通过对分组联接的结果调用DefaultIfEmpty()来执行左外部联接。DefaultIfEmpty()方法从列表中获取指定元素。如果列表为空,则返回默认值。using System;using System.Linq;namespace ConsoleApplication2 class Program static void Main(string args) int intAry1 = 5, 15, 25, 30,40,50,60,70, ; int intAry2 = 10, 20, 30, 40, 50, 60,40,6,2345,23 ; var query1 = from val1 in intAry1 join val2 in intAry2 on val1 equals val2 into valGrp from grp in valGrp.DefaultIfEmpty() select new Val1 = val1,Val2 = grp; foreach (var item in query1) Console.WriteLine(0,item); 注意:左外部联接和分组联接虽然相似但是并不一样。分组联接返回的查询结果是一种分层数据结构,需要使用两层foreach()才能遍历它的结果。而左外部联接是在分组联接的查询结果上再进行一次查询,所以它在join之后还有一个from子句进行查询。在LINQ中,数据源和查询结果实际上都是IEnumerable或IQueryable类型对象,所以可以通过使用普通对象的形式(调用方法、使用属性等)对数据源进行查询或使用查询结果数据。1.IEnumerable接口IEnumerable 泛型接口支持在制定数据集合上进行迭代操作。它定义了一组扩展方法,用来对数据集合中的元素进行遍历、过滤、排序、搜索等操作。在LINQ中,数据源实际 上是实现了接口IEnumerable的类,通过select子句返回的查询结果页是一个实现了 IEnumerable的类。在.NET类库中,IEnumerable接口提供了大量与查询相关的方法。这些方法实际上是以扩展方法的形式定义,但是由于它的作用类型也为IEnumerable接口,所以使用上和成员方法很类似。IEnumerable接口主要成员成员功能Aggregate对序列应用累加器函数,可以指定累加方法Sum计算序列中所有元素的和,返回值有int、long、float、double、decimal类型,并且可以指定元素到数值的映射方法Average计算序列中所有元素的平均值,返回值有int、long、float、double、decimal类型,并且可以指定元素到数值的映射方法Max计算序列中所有元素的最大值,返回值有int、long、float、double、decimal类型,并且可以指定元素到数值的映射方法Min计算序列中所有元素的最小值,返回值有int、long、float、double、decimal类型,并且可以指定元素到数值的映射方法All检查是否序列中所有元素都满足条件,可以指定条件判断方法。如果所有元素都满足条件返回True,否则返回FalseAny检查序列中是否有任何一个元素满足条件,可以指定条件的判断方法。如果有一个以上(含一个)元素满足条件返回True,否则返回FalseContains检查数据系列中是否包含特定的元素,可以指定相等比较方法Count返回序列中满足指定条件的元素的数量,可以指定条件判断方法LongCount返回序列中满足指定条件的元素的长数量,可以指定条件判断方法Cast将IEnumerable中的元素转换为指定的数据类型DefaultIfEmpty返回序列中指定位置的元素。如果序列为空,则返回默认的元素值ElementAt返回序列中指定索引处的元素ElementAtOrDefault返回序列中指定索引处的元素。如果序列为空,则返回默认值First返回序列中满足指定条件的第一个元素,可以指定条件判断方法FirstOrDefault返回序列中满足指定条件的第一个元素。如果不存在则返回默认值,也可以指定条件判断方法Last返回序列中满足指定条件的最后一个元素,可以指定条件判断方法LastOrDefault返回序列中满足指定条件的最后一个元素。如果不存在则返回默认值,也可以指定条件判断方法Single返回序列中满足指定条件的唯一元素。如果不止一个元素满足条件会引发一场,可以指定条件判断方法SingleOrDefault返回序列中满足指定条件的唯一元素。如果不存在则返回默认值,如果不止一个元素满足条件会引发一场,可以指定条件判断方法Reverse反转序列中元素的顺序Distinct返回序列中不重复的元素的集合,可以指定相等比较方法Concat连接两个序列,直接首尾相连。返回结果可能存在重复数据Except获取两个元素集合的差集,可以指定相等比较方法Intersect获取两个元素集合的交集,可以指定相等比较方法Union获取两个元素集合的并集,可以指定相等比较方法SequenceEqual比较两个序列是否相等,可以指定相等比较方法Where根据制定条件对集合中元素进行筛选,返回满足条件的元素集合Skip跳过序列中指定数量的元素,然后返回剩余的元素SkipWhile跳过序列中满足指定条件的元素,然后返回剩余的元素,可以指定条件判断方法Take从序列的开头返回指定数量的连续元素TakeWhile返回从序列开始的满足指定条件的连续元素,可以指定条件判断方法ToArray从IEnumerable创建一个数组ToList从IEnumerable创建一个List从 上表可以看出,IEnumerable提供的方法包括数值运算(Sum、Min、Max、Average)、元素数量(Count、 LongCount)、取值(First、Last、ElementAt等)、提取子集(Skip、SkipWhile、Take、 TakeWhile、)集合操作(Reverse、Concat、Distinct、Except、Intersect、Union、 SequenceEqual等)。这些方法提供了LINQ所需要的所有操作。注意:IEnuerable继承自IEnumerable接口,所以它也包含IEnumerable接口的所有方法,所以还包括Select()、SelectMany()、Repeat()等方法。另外,IQuery接口从IEnumerable派生而来,通常也可以作为数据源使用,它的使用和IEnumerable类似。Lambda表达式实际上是一个匿名函数。它包含表达式和语句,常用于创建委托或表达式目录树类型。所有Lambda表达式都是用Lambda运算 符- =,该运算符读为“goesto”。Lambda运算符的左边是输入参数(可能没有),右边是表达式或语句块。Lambda表达式返回右边表达式 的结果。其基本格式如下:(input paramenters)=expression其中,parameters是一个参数列表,在Lambda只有一个输入参数时可以不适用括号,否则括号是必须的。两个或更多输入参数由括在括号中的逗号分隔,如以下代码所示,包括两个参数x和y。(x,y)= x=y通常Lambda表达式的参数都是可变类型的,由编译器自动确定它的具体类型。但有时编译器难于或无法推断输入类型,就需要为参数显示指定类型,既在参数之前添加参数类型。如下所示的Lambda表达式包括连个参数x和s。其中x是int类型,而s则是string类型。(int x, string s) =s.Length x当Lanbda表达式没有参数时,需要使用空的括号表示,如下所示。其中,“()”表示没有参数,而Amethod()是一个具体的方法,该方法的返回值就是Lambda表达式的结果。() = AMethod()由于Lambda表达式实际是匿名函数,它可以赋值到一个委托,而在IEnumerable的方法中很多都通过函数委托来实现自定义的运算、条件等操作,所以Lambda表达式在Linq中被广泛使用。1.用Where()方法进行筛选using System;using System.Linq;namespace ConsoleApplication3 class Program static void Main(string args) int intary = 1, 2, 3, 4, 5, 6, 7, 8, 89, 10 ; /查询所有能被2整除的元素 var query1 = intary.Where(num = num % 2 = 0); Console.WriteLine(Query1:); foreach (var item in query1) Console.WriteLine(0, item); /查询所有值大于3被索引的元素 var query2 = intary.Where(num, index) = num index * 3); Console.WriteLine(Query2:); foreach (var item in query2) Console.WriteLine(0, item); 2.用OrderBy()方法进行排序using System;using System.Linq;namespace ConsoleApplication3 class Program static void Main(string args) int intary = 1, 2, 3, 4, 5, 6, 7, 8, 89, 10 ; /对所有元素按照%10进行升序排列,这是默认的排序方式 var query1 = intary.OrderBy(val = val % 10 ); Console.WriteLine(Query1:); foreach (var item in query1) Console.WriteLine(0, item); /对所有元素按照%10进行降序排列 var query2 = intary.OrderByDescending(val = val % 10); Console.WriteLine(Query2:); foreach (var item in query2) Console.WriteLine(0, item); 以上的两个排序Demo都是采用默认的int排序比较器,在一些开发中,以下两种情况需要使用特定的数据比较器: 默认的数据类型不能满足特殊的比较需要 自定义的类不存在默认的数据比较器using System;using System.Linq;using System.Collections.Generic;namespace ConsoleApplication3 /自定义int类型比较器,实现IComparable接口 class MyCompare : IComparer public int Compare(int x, int y) int x1 = Math.Abs(x); int y1 = Math.Abs(y); if (x1 y1) return 1; else if (x1 = y1) return 0; else return -1; class Program static void Main(string args) /实例化自定义比较器 MyCompare mc = new MyCompare(); int intary = 1, -2, 3, -4, 5, -6, 7, -8, 9, -10 ; var query1 = intary.OrderBy(val = val, mc); Console.WriteLine(Query1); foreach (var item in query1) Console.WriteLine(0,item); 3.用Skip()、SkipWhile()跳过元素using System;using System.Linq;using System.Collections.Generic;namespace ConsoleApplication3 class Program static void Main(string args) int intary = 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 20, 30, 40 ; /跳过intAry中前3个元素 var query1 = intary.Skip(3); Console.WriteLine(Query1); foreach (var item in query1) Console.WriteLine(0, item); /跳过intAry中小于5的元素 var query2 = intary.SkipWhile(num = num num 5); Console.WriteLine(Query2); foreach (var item in query2) Console.WriteLine(0, item); 5.对元素进行数值计算 Min():求最小值 Max():求最大值 Sum():求和 Average():求平均值using System;using System.Linq;namespace ConsoleApplication3 class Program static void Main(string args) int intary = 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 20, 30, 40 ; var intMin = intary.Min(); var intMax = intary.Max(); var intSum = intary.Sum(); var intAverage = intary.Average(); Console.WriteLine(intarys min=0,max=1,sum=2,average=3,intMin,intMax,intSum,intAverage); string strAry = Kevin, James, Ken, Ben ; var strMin = strAry.Min(); var strMax = strAry.Max(); Console.WriteLine(strArys Min = 0,Max=1,strMin,strMax); 6.用Distinct()消除集合中相等的元素using System;using System.Linq;namespace ConsoleApplication3 class Program static void Main(string args) int intary = 1,1, 2,2, 3, 3, 4, 5; var query1 = intary.Distinct(); foreach (var item in query1) Console.WriteLine(item); 7.用Concat()连接两个集合using System;using System.Linq;namespace ConsoleApplication3 class Program static void Main(string args) string strAry1 = Kevin,James,Ben; string strAry2 = Ken,Joanna,cc; var query1 = strAry1.Concat(strAry2); Console.WriteLine(Query1); foreach (var item in query1) Console.WriteLine(item); var query2 = strAry2.Concat(strAry1); Console.WriteLine(Query2); foreach (var item in query2) Console.WriteLine(item); 注意:Concat()方法是直接将两个集合中的元素连接在一起,不会进行重新排序、过滤等,就算两个集合中元素有重复也同样保留。8.集合操作说到集合,很容易想起并集、交集、差集3种常用操作。在LINQ中,IEnumerable类分别通过Union()、Intersect()、Except完成这3种操作()。using System;using System.Linq;namespace ConsoleApplication3 class Program static void Main(string args) int intAry1 = 1,2,3; int intAry2 = 3,4,5; var query1 = intAry1.Union(intAry2); Console.WriteLine(并集); foreach (var item in query1) Console.WriteLine(item); var query2 = intAry1.Intersect(intAry2); Console.WriteLine(交集); foreach (var item in query2) Console.WriteLine(item); 在.net类库中,LINQ相关类库都在System.Linq命名空间下。该命名空间提供支持使用LINQ进行查询的类和接口,其中最重要的是两个类和两个接口。 IEnumerable接口:它表示可以查询的数据集合,一个查询通常是逐个对集合中的元素进行筛选操作,返回一个新的IEnumerable对象,用来保存查询结果。 IQuerable接口:它继承IEumerable接口,表示一个可以查询的表达式目录树。 Enumerable类,它通过对IEnumerable提供扩展方法,实现LINQ标准查询运算符。包括过滤、导航、排序、查询、联接、求和、求最大值、求最小值等操作。 Queryable类:它通过对IQueryable提供扩展方法,实现LINQ标准查询运算符。包括过滤、导航、排序、查询、联接、求和、求最大值、求最小值等操作。根据数据源类型,可以将LINQ技术分成如下所述的4个主要技术方向。 LINQ to Object:数据源为实现了接口IEnumerable或IQeryable的内存数据集合,这也是LINQ的基础。 LINQ to ADO.NET:数据源为ADO.NET数据集,这里将数据库中的表结构映射到类结构,并通过ADO.NET从数据库中获取到数据集到内存中,通过LINQ进行数据查询。 LINQ to XML:数据源为XML文档,这里通过XElement、XAttribute等类将XML文档数据加载到内存中,通过LINQ进行数据查询。除了这3种常见的数据类型外,.NET3.5还为用户扩展LINQ提供了支持,用户可以根据需要实现第三方的LINQ支持程序,然后通过LINQ获取自定义的数据源。LINQ to SQL语句(1)之WhereWhere操作适用场景:实现过滤,查询等功能。说明:与SQL命令中的Where作用相似,都是起到范围限定也就是过滤作用的,而判断条件就是它后面所接的子句。Where操作包括3种形式,分别为简单形式、关系条件形式、First()形式。下面分别用实例举例下:1.简单形式:例如:使用where筛选在伦敦的客户var q = from c in db.Customers where c.City = London select c;再如:筛选1994 年或之后雇用的雇员:var q = from e in db.Employees where e.HireDate = new DateTime(1994, 1, 1) select e;2.关系条件形式:筛选库存量在订货点水平之下但未断货的产品:var q = from p in db.Products where p.UnitsInStock 10m | p.Discontinued select p;下面这个例子是调用两次where以筛选出UnitPrice大于10且已停产的产品。var q = db.Products.Where(p=p.UnitPrice 10m).Where(p=p.Discontinued);3.First()形式:返回集合中的一个元素,其实质就是在SQL语句中加TOP (1)。简单用法:选择表中的第一个发货方。Shipper shipper = db.Shippers.First();元素:选择CustomerID 为“BONAP”的单个客户Customer cust = db.Customers.First(c = c.CustomerID = BONAP);条件:选择运费大于 10.00 的订单:Order ord = db.Orders.First(o = o.Freight 10.00M);LINQ to SQL语句(2)之Select/DistinctSelect/Distinct操作符适用场景:o(_)o 查询呗。说明:和SQL命令中的select作用相似但位置不同,查询表达式中的select及所接子句是放在表达式最后并把子句中的变量也就是结果返回回来;延迟。Select/Distinct操作包括9种形式,分别为简单用法、匿名类型形式、条件形式、指定类型形式、筛选形式、整形类型形式、嵌套类型形式、本地方法调用形式、Distinct形式。1.简单用法:这个示例返回仅含客户联系人姓名的序列。var q = from c in db.Customers select c.ContactName;注意:这个语句只是一个声明或者一个描述,并没有真正把数据取出来,只有当你需要该数据的时候,它才会执行这个语句,这就是延迟加载 (deferred loading)。如果,在声明的时候就返回的结果集是对象的集合。你可以使用ToList() 或ToArray()方法把查询结果先进行保存,然后再对这个集合进行查询。当然延迟加载(deferred loading)可以像拼接SQL语句那样拼接查询语法,再执行它。2.匿名类型形式:说明:匿名类型是C#3.0中新特性。其实质是编译器根据我们自定义自动产生一个匿名的类来帮助我们实现临时变量的储存。匿名类型还依赖于另外一个 特性:支持根据property来创建对象。比如,var d = new Name = s ;编译器自动产生一个有property叫做Name的匿名类,然后按这个类型分配内存,并初始化对象。但是var d = new s;是编译不通过的。因为,编译器不知道匿名类中的property的名字。例如string c = d;var d = new c; 则是可以通过编译的。编译器会创建一个叫做匿名

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论