《数据库访问方法-LINQ.ppt》由会员分享,可在线阅读,更多相关《数据库访问方法-LINQ.ppt(38页珍藏版)》请在三一办公上搜索。
1、数据库访问方法-LINQ,讲解组员:陈家平、李超、彭兵、于杰、何新佳,LINQ简介,一、什么是LINQ二、LINQ要解决的问题及其优点三、LINQ原理浅析四、LINQ分类五、如何使用LINQ TO SQL,一、什么是LINQ,LINQ是Language Integrated Query的简称,它是集成在.NET编程语言中的一种特性。已成为编程语言的一个组成部分,在编写程序时可以得到很好的编译时语法检查,丰富的元数据,智能感知、静态类型等强类型语言的好处。并且它同时还使得查询可以方便地对内存中的信息进行查询而不仅仅只是外部数据源。LINQ定义了一组标准查询操作符用于在所有基于.NET平台的编程语
2、言中更加直接地声明跨越、过滤和投射操作的统一方式,标准查询操作符允许查询作用于所有基于IEnumerable接口的源,并且它还允许适合于目标域或技术的第三方特定域操作符来扩大标准查询操作符集,更重要的是,第三方操作符可以用它们自己的提供附加服务的实现来自由地替换标准查询操作符,根据LINQ模式的习俗,这些查询喜欢采用与标准查询操作符相同的语言集成和工具支持。,LINQ架构,相关命名空间,二、LINQ要解决的问题,长期以来,开发社区形成以下格局:面向对象与数据访问两个领域长期分裂,各自为政编程语言中的数据类型与数据库中的数据类型形成两套体系。例如:C#中字符串用 string 表示SQL 中字符
3、串用 NVarchar/Varchar/Char 表示SQL 编码体验落后没有智能感应没有严格意义上的强类型和类型检查SQL 和 XML 都有各自的查询语言,而对象没有自己的查询语言,LINQ的使用优点,无需复杂学习过程即可上手编写更少代码即可创建完整应用更快开发错误更少的应用程序无需求助奇怪的编程程序就可合并数据源让开发者开发效率更高任何对象或数据源都可以定制实现Linq适配器,为数据交互带来真正方便,LINQ原理浅析,LINQ(Language Integrated Query)是Visual Studio 2008中的领军人物。借助于LINQ技术,我们可以使用一种类似SQL的语法来查询任
4、何形式的数据。目前为止LINQ所支持的数据源有SQL Server、XML以及内存中的数据集合。开发人员也可以使用其提供的扩展框架添加更多的数据源,例如MySQL、Amazon甚至是Google Desktop。一般来讲,这类查询语句的一个重要特点就是可以并行化执行。虽然有些情况下并行可能会带来一些问题,但这种情况非常少见。这样也就水到渠成地引出了PLINQ这个并行处理的LINQ类库。PLINQ原名为Parallel LINQ,支持XML和内存中的数据集合。执行于远程服务器上的查询语句(例如LINQ to SQL)显然无法实现这个功能。将LINQ语句转换为PLINQ语句极为简单只需要在查询语句
5、中From子句所指定的数据源的最后添加.AsParallel()即可。随后Where、OrderBy和Select子句将自动改为调用这个并行的LINQ版本。,LINQ原理浅析,据MSDN Magazine介绍,PLINQ可以以三种方式执行。第一种是管道处理:一个线程用来读取数据源,而其他的线程则用来处理查询语句,二者同步进行虽然这个单一的消费线程可能并不那么容易与多个生产线程同步。不过若是能够仔细配置好负载平衡的话,仍然会极大地减少内存占用。第二种模式叫做“stop and go”,用于处理结果集需要被一次返回时(例如调用ToList、ToArray或对结果排序)的情况。在这种模式下,将依次完
6、成各个处理过程,并将结果统一返回给消费线程。这个模式在性能上将优于第一种模式,因为它省去了用来保持线程同步所花费的开销。最后一种方法叫做“inverted enumeration”。该方法并不需要实现收集到所有的输出,然后在单一的线程中处理,而是将最终调用的函数通过ForAll扩展传递到每个线程中。这是目前为止最快的一种处理模式,不过这需要传递到ForAll中的函数是线程安全的,且最好不包含任何lock之类的互斥语句。若是PLINQ中任意的一个线程抛出异常,那么所有的其他线程将会被终止。若是抛出了多个异常,那么这些异常将被组合成一个MultipleFailuresException类型的异常,
7、但每个异常的调用堆栈仍会被保留。,二、LINQ分类,LINQ包括五个部分:LINQ to Objects、LINQ to DataSets、LINQ to SQL、LINQ to Entities、LINQ to XML。LINQ to SQL全称基于关系数据的.NET语言集成查询,用于以对象形式管理关系数据,并提供了丰富的查询功能。其建立于公共语言类型系统中的基于SQL的模式定义的集成之上,当保持关系型模型表达能力和对底层存储的直接查询评测的性能时,这个集成在关系型数据之上提供强类型。LINQ to XML在System.Xml.LINQ命名空间下实现对XML的操作。采用高效、易用、内存中的
8、XML工具在宿主编程语言中提供XPath/XQuery功能等。,LINQ查询表达式,static void Main(string args)int ary=1,3,5,78,9,12;var query1=from val in ary select val;foreach(var item in query1)Console.Write(0,item);,LINQ查询表达式 隐式类型,从 Visual C#3.0 开始,在方法范围中声明的变量可以具有隐式类型 var。隐式类型的本地变量是强类型变量(就好像您已经声明该类型一样),但由编译器确定类型。下面的两个 i 声明在功能上是等效的:va
9、r i=10;/隐式类型 int i=10;/显式类型 备注:var关键字声明的对象必须是在声明时就必须能推断出其类型的,所以,声明一个var类型对象时候就就必须对它进行初始化,让编译器能推断出它的类型,所以,这样的代码是无法编译过的 var query2;query2=1;,LINQ查询表达式 用from子句指定数据源,数据源是实现泛型接口IEnumerble或IQueryable的类对象。IEnumerble可以简单理解成一个包含多个元素的列表(或数据库中的表),可以用foreach遍历它的所有元素,从而轻松完成查询操作。每个Linq查询都以from字句开始,from子句包括以下两个功能。
10、指定查询将采用的数据源定义一个本地变量,表示数据源中的单个元素from localVar in dataSource;,LINQ查询表达式 用select子句指定数据源,在Linq查询中,select子句和from子句都是必备子句。Linq查询表达式必须以select或group子句结束。Select子句指定在执行查询时产生结果的数据集中元素的类型,它的格式如下所示:select elementselect子句中如果不指定元素的具体类型,编译器会将查询中元素的类型自动设为 select子句中元素的具体类型select子句中要选择的目标数据不仅可以为数据源中的元素,还可以是该元素的不同操作结果,
11、包括属性、方法和运算等。在某些特殊的场合下,往往查询结果只是临时使用一下,而且查询结果的数据包括很多字段,并非简单的一个属性。则可以在select子句中使用匿名类型来解决这类问题匿名类型提供了一种方便的方法,可用来将一组只读属性封装到单个对象中,而无需首先显式定义一个类型。类型名由编译器生成,并且不能在源代码级使用。这些属性的类型由编译器推断。下面的示例演示一个用两个分别名为 Amount 和 Message 的属性初始化的匿名类型。var v=new Amount=108,Message=Hello;,LINQ查询表达式 用where子句指定筛选条件,格式:where expression示
12、例:int ary=1,6,98,15,30,60;var q1=from v1 in ary where v1 15 select v1;var q2=from v2 in ary where(v2 10),LINQ查询表达式 用orderby子句进行排序,格式:orderby expression sortTypeelement:是要进行排序的字段,它可以是数据源中的元素,也可以是对元素的操作结果。sortType:可选参数,表示排序类型,包括升序(ascending)和降序(descending)两个可选值示例:int ary=1,6,98,15,30,60;var q1=from v1
13、 in ary orderby v1 select v1;foreach(var qi1 in q1)Console.Write(0,qi1);var q2=from v2 in ary orderby v2 descending select v2;var q3=from st in stAry orderby st.Name.Length ascending,st.Age descending select st;,LINQ查询表达式 用group子句进行分组,格式:group element by keyelement:作为查询结果返回的元素。key:表示分组条件Group子句返回类型为
14、IGrouping的查询结果。其中Tkey的类型为参数key的数据类型,TElement的类型是参数element的数据类型。示例:var q=from st in stAry group st by st.Sex;foreach(var grp in q)Console.WriteLine(grp.Key);foreach(var val in grp)Console.WriteLine(t0,val);,LINQ查询表达式 分组后排序,格式:group element by key into tmpGrp说明:有时需要对分组的结果进行排序,再次查询等操作。这就需要使用into关键字将gro
15、up的结果保存到一个临时变量,并且必须使用新的Select或group子句对其进行重新查询,也可以使用orderby进行排序、用where进行过滤等操作。示例:var q=from st in stAry group st by st.Age into stGrp orderby stGrp.Key descending select stGrp;foreach(var qi in q)/外层遍历学生年龄 Console.WriteLine(0岁的学生:,qi.Key);foreach(var val in qi)/内层遍历学生信息 Console.WriteLine(t0,val);,LIN
16、Q查询表达式 用from子句进行复核查询1,说明:查询q采用两个from子句实现复合查询,第二个from子句的元素从第一个from子句的结果中再次查询示例:var q=from st in stAry from scr in st.Scores where scr.Score 80 group scr by st.Name;foreach(var grp in q)Console.WriteLine(grp.Key);foreach(var item in grp)Console.WriteLine(t0,item);,LINQ查询表达式 用from子句进行复核查询2,说明:在多个数据源上进行
17、排序 int intAry1=5,15,25,30,33,50;int intAry2=10,20,30,40,50,60,70,80,90,100;var q=from v1 in intAry1 from v2 in intAry2 where v2%v1=0 group v2 by v1;foreach(var grp in q)Console.WriteLine(n分组标准:0,grp.Key);foreach(var val in grp)Console.Write(t0,val);,LINQ查询表达式 用join子句进行联接,说明:在查询语言中,通常需要使用联接操作。在linq中,
18、可以通过join子句实现联接操作。Join子句可以将来自不同源序列,并且在对象模型中没有直接关系的元素相关联,唯一的要求是每个源中需要共享某个可以进行比较,以判断是否相等的值。内部链接分组联接左外部链接,LINQ查询表达式 用join子句进行内部联接,说明:在查询语言中,通常需要使用联接操作。在linq中,可以通过join子句实现联接操作。Join子句可以将来自不同源序列,并且在对象模型中没有直接关系的元素相关联,唯一的要求是每个源中需要共享某个可以进行比较,以判断是否相等的值。内部链接分组联接左外部链接,LINQ查询表达式 用join子句进行分组联接,说明:需要将查询结果按照第一个数据集中的
19、元素进行分组。公式:join element in dataSource on exp1 equals exp2 into grpNameinto关键字表示将这些数据分组并保存到grpName中。备注:分组联接可用于产生分层的数据结果,它将第一个集合中的每个元素与第二个集合中的一组相关元素进行配对。即使第一个集合中的元素在第二个集合中没有配对元素,也会为它产生一个空的分组对象。示例:var query1=from val1 in intAry1 join val2 in intAry2 on val1%5 equals val2%15 into val2Grp select new V1=va
20、l1,V2GRP=val2Grp;foreach(var obj in query1)Console.WriteLine(0:,obj.V1);foreach(var val in obj.V2GRP)Console.Write(0,val);Console.WriteLine();,LINQ查询表达式 用join子句进行左外部联接,说明:返回第一个集合中的所有元素,无论它是否在第二个集合中有相关元素。在linq中,通过对分组联接的结果调用DefaultIfEmpty()来执行左外部联接。DefaultIfEmpty()方法从列表中获取指定元素。如果列表为空,则返回默认值。var query1
21、=from val1 in intAry1 join val2 in intAry2 on val1%5 equals val2%15 into val2Grp from grp in val2Grp.DefaultIfEmpty()select new V1=val1,V2GRP=grp;foreach(var obj in query1)Console.WriteLine(0,obj);备注:左外联接和分组联接虽然相似但是并非一样。分组联接返回的查询结果是一种分层数据结构。需要使用两层foreach才能遍历它的结果。而左外联接是在分组联接的查询结果上 再进行一次查询,所以在join之后还有
22、一个from子句进行查询。,LINQ查询方法,在linq中,数据源和查询结果实际上都是IEnumerable或IQueryable类型对象,所以可以通过使用普通对象的形式(调用方法、使用属性)对数据源进行查询或使用查询结果数据。IEnumerable泛型接口支持在指定数据集合上进行迭代操作。它定义了一组扩展方法,用来对数据集合中的元素进行遍历、过滤、排序、搜索、定位等操作。,LINQ查询方法 扩展方法,扩展方法使您能够向现有类型“添加”方法,而无需创建新的派生类型、重新编译或以其他方式修改原始类型。扩展方法是一种特殊的静态方法,但可以像扩展类型上的实例方法一样进行调用。扩展方法被定义为静态方法
23、,但它们是通过实例方法语法进行调用的。它们的第一个参数指定该方法作用于哪个类型,并且该参数以 this 修饰符为前缀。仅当您使用 using 指令将命名空间显式导入到源代码中之后,扩展方法才位于范围中。示例 public static class MyExtend public static void Foreach(this int numbers)foreach(int i in numbers)Console.Write(0,i);,LINQ查询方法 Lambda表达式,“Lambda 表达式”是一个匿名函数,它可以包含表达式和语句,并且可用于创建委托或表达式树类型。所有 Lambda
24、表达式都使用 Lambda 运算符=,该运算符读为“goes to”。该 Lambda 运算符的左边是输入参数(如果有),右边包含表达式或语句块。Lambda表达式返回右边表达式的结果Lambda 表达式 x=x*x 读作“x goes to x times x”。可以将此表达式分配给委托类型格式:(input parameters)=expressiondelegate int del(int i);static void Main(string args)del myDelegate=x=x*x;int j=myDelegate(5);/j=25,LINQ查询方法 用where进行筛选,在
25、linq查询中,where子句可以用IEnumerable.Where()方法来实现。该方法接受一个函数委托作为参数,该委托指定过滤的具体实现,返回符合条件的元素集合。示例:/查询intAry中所有能被5整除的元素 var query1=intAry.Where(num=num%5=0);Console.WriteLine(Query1);foreach(var val in query1)Console.Write(0,val);/查询intAry中所有值大于3倍索引的元素 var query2=intAry.Where(num,index)=num index*3);Console.Wri
26、teLine(nQuery2);foreach(var val in query2)Console.Write(0,val);,LINQ查询方法 用orderby进行排序,在linq查询中,Orderby子句可以从小到大排序元素,也可以用OrderByDescending方法从大到小排序元素。示例:/查询intAry中所有的元素,按照被10%的结果升序排列 var query1=intAry.OrderBy(num=num%10);Console.WriteLine(Query1);foreach(var val in query1)Console.Write(0,val);/查询intAry
27、中所有的元素,按照被10%的结果降序排列 var query2=intAry.OrderByDescending(num=num%10);Console.WriteLine(nQuery2);foreach(var val in query2)Console.Write(0,val);,LINQ查询方法 自定义比较器,/自定义的int类型比较器,实现IComparer接口class MyComparer:IComparer public int Compare(int x,int y)int x1=Math.Abs(x);int y1=Math.Abs(y);if(x1 y1)return 1
28、;else if(x1=y1)return 0;return-1;,static void UseOrderByDef()MyComparer mc=new MyComparer();/查询query3对intAry中所有元/素使用自定义比较器从小到大/排序 var query3=intAry.OrderBy(val=val,mc);Console.WriteLine(Query3);foreach(var v in query3)Console.Write(0,v);,LINQ查询方法 用skip、skipwhile跳过元素,说明:明确跳过某些元素,只提取剩下的元素作为查询结果。示例:/查询
29、query1跳过数组前3个元素var query1=intAry.Skip(3);foreach(var val in query1)Console.Write(0,val);Console.WriteLine();/跳过绝对值小于10的元素var query2=intAry.SkipWhile(num=num/10=0);foreach(var val in query2)Console.Write(0,val);/跳过绝对值小于10的元素,并再次忽略前2个元素var query3=intAry.SkipWhile(num=num/10=0).Skip(2);foreach(var val
30、in query3)Console.Write(0,val);,LINQ查询方法 用Max、Min、Sum、Average进行数值运算,说明:明确指定要提取的元素作为查询结果。示例:var intMax=intAry.Max();var intMin=intAry.Min();var intAverage=intAry.Average();var intSum=intAry.Sum();var strMax=strAry.Max(s=s.Length);,LINQ查询方法 用Distinct消除集合中相等的元素1,说明:消除集合中相等的元素示例:var query1=intAry.Distin
31、ct();foreach(var item in query1)Console.Write(0,item);,LINQ查询方法 用Distinct消除集合中相等的元素2,说明:自定义相等比较器示例:/首字符相同且长度一样的字符串被认定为相同class MyStrEqualComparer:IEqualityComparer public bool Equals(string x,string y)bool temp=x.Substring(0,1)=y.Substring(0,1);return temp;public int GetHashCode(string obj)return obj
32、.Length;/将字符串的长度作为它的Hash码 static void UseDistinctComplex()/使用自定义的字符串相等比较器 MyStrEqualComparer msc=new MyStrEqualComparer();var query2=strAry.Distinct(msc);foreach(var item in query2)Console.Write(0,item);,LINQ查询方法 用union等进行集合操作,说明:常见的集合运算有并集,交集和差集。在Linq中,IEnumerable类分别通过Union(),Intersect(),Except()完成
33、这3个操作。Union():该方法对集合A和集合B进行并集操作,返回两个集合中的所有元素,相同的元素只出现一次。Intersect():该方法对集合A和集合B进行交集操作,返回两个集合中的相等元素。Except():该方法对集合A和集合B进行差集操作,返回在集合A中有,但是在集合B中没有的元素。,LINQ查询方法 用union等进行集合操作,示例:int intAry1=1,3,5,8,10,12,33,45,12,2;int intAry2=2,5,10,6,7,11,23,25,45,33;var q1=intAry1.Union(intAry2);var q2=intAry1.Union(intAry2);var q3=intAry1.Except(intAry2);var q4=intAry2.Except(intAry1);,三、如何使用LINQ TO SQL,第一步:建立dbml(Database Mark Language.数据库描述语言,是一种XML格式的文档,用来描述数据库,有点类似Nhibernate的映射文件)第二步:创建一个ASP.NET页面,页面加入一个GridView控件第三步:编写代码进行数据绑定第四步:执行代码,Thank You!,