LINQ中文教程.docx

上传人:b****8 文档编号:30387547 上传时间:2023-08-14 格式:DOCX 页数:105 大小:419.23KB
下载 相关 举报
LINQ中文教程.docx_第1页
第1页 / 共105页
LINQ中文教程.docx_第2页
第2页 / 共105页
LINQ中文教程.docx_第3页
第3页 / 共105页
LINQ中文教程.docx_第4页
第4页 / 共105页
LINQ中文教程.docx_第5页
第5页 / 共105页
点击查看更多>>
下载资源
资源描述

LINQ中文教程.docx

《LINQ中文教程.docx》由会员分享,可在线阅读,更多相关《LINQ中文教程.docx(105页珍藏版)》请在冰豆网上搜索。

LINQ中文教程.docx

LINQ中文教程

LINQ中文教程

目录

1初体验之LINQtoObject-1-

2一步一步学Linqtosql-4-

2.1预备知识-4-

2.1.1隐含类型局部变量-4-

2.1.2匿名类型-4-

2.1.3扩展方法-5-

2.1.4自动属性-6-

2.1.5对象初始化器-6-

2.1.6集合初始化器-7-

2.1.7Lambda表达式-7-

2.1.8查询句法-8-

2.2DataContext与实体-9-

2.2.1定义实体类-10-

2.2.2强类型DataContext-11-

2.2.3日志功能-12-

2.2.4探究查询-12-

2.2.5执行查询-13-

2.2.6创建数据库-14-

2.2.7使用DbDataReader数据源-15-

2.3增删改-16-

2.3.1示例数据库-16-

2.3.2生成实体类-16-

2.3.3简易留言簿-17-

2.4查询句法-24-

2.4.1select-24-

2.4.2where-27-

2.4.3orderby-28-

2.4.4分页-29-

2.4.5分组-30-

2.4.6distinct-32-

2.4.7union-33-

2.4.8concat-34-

2.4.9取相交项-35-

2.4.10排除相交项-36-

2.4.11子查询-37-

2.4.12in操作-38-

2.4.13join-39-

2.5储过程-40-

2.5.1普通存储过程-40-

2.5.2带参数的存储过程-42-

2.5.3带返回值的存储过程-43-

2.5.4多结果集的存储过程-44-

2.5.5使用存储过程新增数据-45-

2.5.6使用存储过程删除数据-47-

2.5.7使用存储过程更改数据-48-

2.6探究特性-50-

2.6.1延迟执行-50-

2.6.2主键缓存-57-

2.6.3DataContext隔离-58-

2.7并发与事务-59-

2.7.1检测并发-59-

2.7.2解决并发-60-

2.7.3事务处理-64-

2.8继承与关系-66-

2.8.1论坛表结构-66-

2.8.2实体继承的定义-67-

2.8.3实体继承的使用-69-

2.8.4实体关系的定义-71-

2.8.5实体关系的使用-73-

2.9其它补充-77-

2.9.1外部映射文件-77-

2.9.2处理空值-77-

2.9.3已编译查询-78-

2.9.4撤销提交-79-

2.9.5批量操作-80-

2.10分层构架的例子-80-

2.10.1项目介绍-80-

2.10.2生成映射文件和实体-81-

2.10.3编写数据访问服务-81-

2.10.4WCF服务端与客户端-84-

2.10.5调用服务-86-

3学习LinqToXml-89-

3.1概述-89-

3.1.1直接使用XML元素-90-

3.1.2命名空间-91-

3.2编程概述-92-

3.2.1类概述-92-

3.2.2XDocument类概述-94-

3.2.3XElement类概述-96-

3.3Linq操作XML-98-

3.3.1编程创建XML文档-98-

3.3.2查询创建XML文档-99-

3.3.3加载和解析XML内容-100-

3.3.4遍历内存中的XML文档-100-

3.3.5修改XML文档-102-

1初体验之LINQtoObject

VS2008的发布,最激动人心的莫过是LINQ的诞生。

What‘sLINQ?

LanguageIntegratedQuery是也。

说得再明白一些,这是编程语言的一种新特性,能够将数据查询语句集成到编程语言中。

目前,支持LINQ的语言有C#和VB。

为啥会有LINQ,主要还是因为现在的数据格式越来越多,数据库、XML、数组、哈希表……每一种都有自己操作数据的方式,学起来费事费力。

于是,就有了LINQ诞生的理由——以一种统一的方式操作各种数据源,减少数据访问的复杂性。

LINQ带来很多开发上的便利。

首先,他可以利用VisualStudio这个强大的IDE(这话决不是吹,VisualStudio绝对是最好用的开发工具之一),至少用VisualStudio来写SQL语句,可以有智能感知了,比起从前用查询分析器写存储过程的感觉好多了!

其次,它可以把数据当成一个对象来操作,即Data==Object?

的问题。

LINQ目前可以对XML,Object,SQL做数据访问,今后还会有LINQtoEntity的功能。

说来惭愧,我也是刚刚才接触LINQ,先从最简单的开始吧,做一个LINQtoObject的例子,实现一个对数组的操作。

这个例子套用了今年TechED中海洋兄讲的例子,在此声明。

在这个例子中,我会先通过GetMethods的方法,拿到string的所有方法,接下来,就看LINQ的厉害了,这里是选出所有非静态的方法签名。

MethodInfo[] methods = typeof(string).GetMethods();

var result = from m in methods

where m.IsStatic !

=true

select m.Name;

foreach (var r in result)

{

Console.WriteLine(r.ToString());

}

Console.ReadLine();

例子虽然简单,确能从中看出LINQ的一些端倪。

首先,var是什么东东?

看起来,有点像javascript里面的弱类型的变量声明。

但是,C#是强类型的,尽管你用var来声明,编译器还是可以根据上下文推倒出它当前的类型。

比如这个例子里面,result就是IEnumerable类型的。

在这里面,写IEnumerable和写var是一样效果的,显然,var会简单得多。

你不用考虑数据操作的返回值是什么类型,还能享受强类型声明带来的方便实惠……

还有fromminmethods这句,m是什么东西,m是隐式声明的一个变量,尽管没有声明,但编译器根据上下文,推断出它的类型是MethodInfo型的!

.NETFramework3.5的编译器的确是聪明了很多^^。

上面这个例子运行起来的结果中有很多重复的记录,我们可以用distinct()来过滤掉重复的,和SQL还是很相似的说。

var result = (from m in methods

where m.IsStatic !

=true

select m.Name).Distinct();

或者用groupby也可以

var result = from m in methods

where m.IsStatic !

=true

group m by m.Name;

但是这样子写,在输出的时候,显示的是System.Linq.Lookup`2+Grouping[System.String,System.Reflection.MethodInfo],所以,再做一些修改

var result = from m in methods

where m.IsStatic !

=true

group m by m.Name into g

select new { MethodName = g.Key, Overload = g.Count() };

这里面又有一些新鲜的了——selectnew{MethodName=g.Key,Overload=g.Count()},先来看一个简单一些的例子:

class MyClass

{

public string MethodName { get; set; }

public int Overload { get; set; }

}

class Program

{

MyClass mc = new MyClass { MethodName = "aaa", Overload = 2 };

}

大括号里面的叫类初始化器,省去了构造函数,在new的同时,给对象的属性赋值。

这时候再回来看看selectnew{MethodName=g.Key,Overload=g.Count()},跟这个类初始化器很像吧,但是它更偷懒,new一个新对象,居然连类名都不写。

没错,这就叫匿名类。

不用写类的声明,直接实例化。

类的名字是由编译器在编译的时候自动生成的,也就是说,你在new的时候根本不知道这个类叫啥名,因此,这里就只能用var了。

这就更看出var的厉害了,不仅仅是写起来方便这么简单,在用到匿名类的时候,没有类名,这时候只能用var,嘿嘿!

2一步一步学Linqtosql

2007-08-24作者:

lovecherry出处:

天极网

2.1预备知识

什么是Linqtosql?

Linqtosql(或者叫DLINQ)是LINQ(.NET语言集成查询)的一部分,全称基于关系数据的.NET语言集成查询,用于以对象形式管理关系数据,并提供了丰富的查询功能,它和Linqtoxml、Linqtoobjects、Linqtodataset、Linqtoentities等组成了强大的LINQ。

要学好LINQ查询语法,就不得不先理解C#3.0的一些新特性,下面一一简单介绍。

2.1.1隐含类型局部变量

var age = 26;

var username = "zhuye";

var userlist = new [] {"a","b","c"};

foreach(var user in userlist)

Console.WriteLine(user);

纯粹给懒人用的var关键字,告诉编译器(对于CLR来说,它是不会知道你是否使用了var,苦力是编译器出的),你自己推断它的类型吧,我不管了。

但是既然让编译器推断类型就必须声明的时候赋值,而且不能是null值。

注意,这只能用于局部变量,用于字段是不可以的。

2.1.2匿名类型

var data = new {username = "zhuye",age = 26};

Console.WriteLine("username:

{0} age:

{1}", data.username, data.age);

匿名类型允许开发人员定义行内类型,无须显式定义类型。

常和var配合使用,var用于声明匿名类型。

定义一个临时的匿名类型在LINQ查询句法中非常常见,我们可以很方便的实现对象的转换和投影。

2.1.3扩展方法

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;

}

}

// 调用扩展方法

Console.WriteLine("123456".MD5Hash());

Console.WriteLine("1".In(new[]{"1","2","3"}));

很多时候我们需要对CLR类型进行一些操作,苦于无法扩展CLR类型的方法,只能创建一些helper方法,或者生成子类。

扩展方法使得这些需求得以实现,同时也是实现LINQ的基础。

定义扩展方法需要注意,只能在静态类中定义并且是静态方法,如果扩展方法名和原有方法名发生冲突,那么扩展方法将失效。

2.1.4自动属性

public class Person

{

public string username { get; protected set; }

public int age { get; set; }

public Person()

{

this.username = "zhuye";

}

}

Person p = new Person();

//p.username = "aa";

Console.WriteLine(p.username);

意义不是很大,纯粹解决机械劳动。

编译器自动为你生成get、set操作以及字段,并且你不能使用字段也不能自定义get、set操作,不过你可以分别定义get和set的访问级别。

2.1.5对象初始化器

public class Person

{

public string username { get; set; }

public int age { get; set; }

public override string ToString()

{

return string.Format("username:

{0} age:

{1}", this.username, this.age);

}

}

Person p = new Person() {username = "zhuye", age=26};

Console.WriteLine(p.ToString());

编译器会自动为你做setter操作,使得原本几行的属性赋值操作能在一行中完成。

这里需要注意:

●允许只给一部分属性赋值,包括internal访问级别

●可以结合构造函数一起使用,并且构造函数初始化先于对象初始化器执行

2.1.6集合初始化器

public class Person

{

public string username { get; set; }

public int age { get; set; }

public override string ToString()

{

return string.Format("username:

{0} age:

{1}", this.username, this.age);

}

}

var persons = new List {

new Person {username = "a", age=1},

new Person {username = "b", age=2}};

foreach(var p in persons)

Console.WriteLine(p.ToString());

编译器会自动为你做集合插入操作。

如果你为Hashtable初始化的话就相当于使用了两个对象初始化器。

2.1.7Lambda表达式

var list = new [] { "aa", "bb", "ac" };

var result = Array.FindAll(list, s => (s.IndexOf("a") > -1));

foreach (var v in result)

Console.WriteLine(v);

其实和2.0中的匿名方法差不多,都是用于产生内联方法,只不过Lambda表达式的语法更为简洁。

语法如下:

●(参数列表)=>表达式或者语句块

●其中:

⏹参数个数:

可以有多个参数,一个参数,或者无参数。

⏹表达式或者语句块:

这部分就是我们平常写函数的实现部分(函数体)。

前面的示例分别是1个参数的例子,下面结合扩展方法来一个复杂的例子:

public delegate int mydg(int a, int b);

public static class LambdaTest

{

public static int oper(this int a, int b, mydg dg)

{

return dg(a, b);

}

}

Console.WriteLine(1.oper(2, (a, b) => a + b));

Console.WriteLine(2.oper(1, (a, b) => a - b));

2.1.8查询句法

var persons = new List {

new Person {username = "a", age=19},

new Person {username = "b", age=20},

new Person {username = "a", age=21},

};

var selectperson = from p in persons where p.age >= 20 select p.username.ToUpper();

foreach(var p in selectperson)

Console.WriteLine(p);

查询句法是使用标准的LINQ查询运算符来表达查询时一个方便的声明式简化写法。

该句法能在代码里表达查询时增进可读性和简洁性,读起来容易,也容易让人写对。

VisualStudio对查询句法提供了完整的智能感应和编译时检查支持。

编译器在底层把查询句法的表达式翻译成明确的方法调用代码,代码通过新的扩展方法和Lambda表达式语言特性来实现。

上面的查询句法等价于下面的代码:

var selectperson = persons.Where(p=>p.age>=20).Select(p=>p.username.ToUpper());

LINQ查询句法可以实现90%以上T-SQL的功能(由于T-SQL是基于二维表的,所以LINQ的查询语法会比T-SQL更简单和灵活),但是由于智能感应的原因,select不能放在一开始就输入。

2.2DataContext与实体

DataContext类型(数据上下文)是System.Data.Linq命名空间下的重要类型,用于把查询句法翻译成SQL语句,以及把数据从数据库返回给调用方和把实体的修改写入数据库。

DataContext提供了以下一些使用的功能:

●以日志形式记录DataContext生成的SQL

●执行SQL(包括查询和更新语句)

●创建和删除数据库

DataContext是实体和数据库之间的桥梁,那么首先我们需要定义映射到数据表的实体。

2.2.1定义实体类

using System.Data.Linq.Mapping;

[Table(Name = "Customers")]

public class Customer

{

    [Column(IsPrimaryKey = true)]

    public string CustomerID {get; set;}

    [Column(Name = "ContactName")]

    public string Name { get; set; }

    [Column]

    public string City {get; set;}

}

以Northwind数据库为例,上述Customers类被映射成一个表,对应数据库中的Customers表。

然后在类型中定义了三个属性,对应表中的三个字段。

其中,CustomerID字段是主键,如果没有指定Column特性的Name属性,那么系统会把属性名作为数据表的字段名,也就是说实体类的属性名就需要和数据表中的字段名一致。

现在,创建一个ASP.NET页面,然后在页面上加入一个GridView控件,使用下面的代码进行绑定数据:

using System.Data.Linq;

DataContext ctx = new DataContext("server=xxx;database=Northwind;uid=xxx;pwd=xxx");

Table Customers = ctx.GetTable();

GridView1.DataSource = from c in Customers where c.CustomerID.StartsWith("A") select new {顾客ID=c.CustomerID, 顾客名=c.Name, 城市=c.City};

GridView1.DataBind();

使用DataContext类型把实体类和数据库中的数据进行关联。

你可以直接在DataContext的构造方法中定义连接字符串,也可以使用IDbConnection:

using System.Data.SqlClient;

IDbConnection conn = new SqlConnection("server=xxx;database=Northwind;uid=xxx;pwd=xxx");

DataContext ctx = new DataContext(conn);

之后,通过GetTable获取表示底层数据表的Table类型,显然,数据库中的Customers表的实体是Customer类型。

随后的查询句法,即使你不懂SQL应该也能看明白。

从Customers表中找出CustomerID以“A”开头的记录,并把CustomersID、Name以及City封装成新的匿名类型进行返回。

结果如下图:

2.2.2强类型DataContext

 public partial class NorthwindDataContext :

 DataContext

{

public Table Customers;

public NorthwindDataContext(IDbConnection connection) :

 base(connection) { }

public NorthwindDataContext(string connection) :

 base(connection) { }

}

强类型数据上下文使代码更简洁:

NorthwindDataContext ctx = new NorthwindDataContext("server=xxx;database=Northwind;uid=xxx;pwd=xxx");

GridView1.DataSource = from c in ctx.Customers where c.CustomerID.StartsWith("A") select new { 顾客ID = c.CustomerID, 顾客名 = c.Name, 城市 = c.City };

GridV

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 人文社科 > 教育学心理学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1