LINQ.docx

上传人:b****1 文档编号:13612712 上传时间:2023-06-15 格式:DOCX 页数:17 大小:35.30KB
下载 相关 举报
LINQ.docx_第1页
第1页 / 共17页
LINQ.docx_第2页
第2页 / 共17页
LINQ.docx_第3页
第3页 / 共17页
LINQ.docx_第4页
第4页 / 共17页
LINQ.docx_第5页
第5页 / 共17页
LINQ.docx_第6页
第6页 / 共17页
LINQ.docx_第7页
第7页 / 共17页
LINQ.docx_第8页
第8页 / 共17页
LINQ.docx_第9页
第9页 / 共17页
LINQ.docx_第10页
第10页 / 共17页
LINQ.docx_第11页
第11页 / 共17页
LINQ.docx_第12页
第12页 / 共17页
LINQ.docx_第13页
第13页 / 共17页
LINQ.docx_第14页
第14页 / 共17页
LINQ.docx_第15页
第15页 / 共17页
LINQ.docx_第16页
第16页 / 共17页
LINQ.docx_第17页
第17页 / 共17页
亲,该文档总共17页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

LINQ.docx

《LINQ.docx》由会员分享,可在线阅读,更多相关《LINQ.docx(17页珍藏版)》请在冰点文库上搜索。

LINQ.docx

LINQ

LINQ介绍

语言集成查询(LINQ)是VisualStudio2008和.NETFramework3.5版中引入的一项创新功能,它在对象领域和数据领域之间架起了一座桥梁。

传统上,针对数据的查询都是以简单的字符串表示,而没有编译时类型检查或IntelliSense支持。

此外,您还必须针对以下各种数据源学习一种不同的查询语言:

SQL数据库、XML文档、各种Web服务等等。

LINQ使查询成为C#和VisualBasic中的一流语言构造。

您可以使用语言关键字和熟悉的运算符针对强类型化对象集合编写查询。

下图显示了一个用C#语言编写的、不完整的LINQ查询,该查询针对SQLServer数据库,并具有完全类型检查和IntelliSense支持。

在VisualStudio中,可以用VisualBasic或C#为以下数据源编写LINQ查询:

SQLServer数据库、XML文档、ADO.NET数据集,以及支持IEnumerable或泛型IEnumerable(OfT)接口的任意对象集合。

此外,还计划了对ADO.NETEntityFramework的LINQ支持,并且第三方为许多Web服务和其他数据库实现编写了LINQ提供程序。

LINQ查询既可在新项目中使用,也可在现有项目中与非LINQ查询一起使用。

唯一的要求是项目应面向.NETFramework3.5或更高版本。

基本LINQ查询操作

本主题简要介绍LINQ查询表达式,以及您在查询中执行的一些典型类型的操作。

下面各主题中提供了更详细的信息:

LINQ查询表达式(C#编程指南)

标准查询运算符概述

注意

如果您已熟悉查询语言(如SQL或XQuery),则可以跳过本主题的大部分内容。

阅读下一节中的“from子句”来了解LINQ查询表达式中的子句的顺序。

获取数据源

--------------------------------------------------------------------------------

在LINQ查询中,第一步是指定数据源。

像在大多数编程语言中一样,在C#中,必须先声明变量,才能使用它。

在LINQ查询中,最先使用from子句的目的是引入数据源(customers)和范围变量(cust)。

C#复制

//queryAllCustomersisanIEnumerable

varqueryAllCustomers=fromcustincustomers

                        selectcust;

范围变量类似于foreach循环中的迭代变量,但在查询表达式中,实际上不发生迭代。

执行查询时,范围变量将用作对customers中的每个后续元素的引用。

因为编译器可以推断cust的类型,所以您不必显式指定此类型。

其他范围变量可由let子句引入。

有关更多信息,请参见let子句(C#参考)。

注意  

对于非泛型数据源(如ArrayList),必须显式类型化范围变量。

有关更多信息,请参见如何:

使用LINQ查询ArrayList和from子句(C#参考)。

筛选

--------------------------------------------------------------------------------

也许最常用的查询操作是应用布尔表达式形式的筛选器。

此筛选器使查询只返回那些表达式结果为true的元素。

使用where子句生成结果。

实际上,筛选器指定从源序列中排除哪些元素。

在下面的示例中,只返回那些地址位于伦敦的customers。

C#复制

varqueryLondonCustomers=fromcustincustomers

                          wherecust.City=="London"

                          selectcust;

您可以使用熟悉的C#逻辑AND和OR运算符来根据需要在where子句中应用任意数量的筛选表达式。

例如,若要只返回位于“伦敦”AND姓名为“Devon”的客户,您应编写下面的代码:

C#复制

wherecust.City=="London"&&cust.Name=="Devon"

若要返回位于伦敦或巴黎的客户,您应编写下面的代码:

C#复制

wherecust.City=="London"||cust.City=="Paris"

有关更多信息,请参见where子句(C#参考)。

Ordering

--------------------------------------------------------------------------------

通常可以很方便地将返回的数据进行排序。

orderby子句将使返回的序列中的元素按照被排序的类型的默认比较器进行排序。

例如,下面的查询可以扩展为按Name属性对结果进行排序。

因为Name是一个字符串,所以默认比较器执行从A到Z的字母排序。

C#复制

varqueryLondonCustomers3=

    fromcustincustomers

    wherecust.City=="London"

    orderbycust.Nameascending

    selectcust;

若要按相反顺序(从Z到A)对结果进行排序,请使用orderby…descending子句。

有关更多信息,请参见orderby子句(C#参考)。

分组

--------------------------------------------------------------------------------

使用group子句,您可以按指定的键分组结果。

例如,您可以指定结果应按City分组,以便位于伦敦或巴黎的所有客户位于各自组中。

在本例中,cust.City是键。

注意  

在下面的示例中,类型是显式的以更好地说明概念。

您也可以对custQuery、group和customer使用隐式类型以让编译器确定准确的类型。

C#复制

//queryCustomersByCityisanIEnumerable>

  varqueryCustomersByCity=

      fromcustincustomers

      groupcustbycust.City;

  //customerGroupisanIGrouping

  foreach(varcustomerGroupinqueryCustomersByCity)

  {

      Console.WriteLine(customerGroup.Key);

      foreach(CustomercustomerincustomerGroup)

      {

          Console.WriteLine("    {0}",customer.Name);

      }

  }

在使用group子句结束查询时,结果采用列表的列表形式。

列表中的每个元素是一个具有Key成员及根据该键分组的元素列表的对象。

在循环访问生成组序列的查询时,您必须使用嵌套的foreach循环。

外部循环用于循环访问每个组,内部循环用于循环访问每个组的成员。

如果您必须引用组操作的结果,可以使用into关键字来创建可进一步查询的标识符。

下面的查询只返回那些包含两个以上的客户的组:

C#复制

//custQueryisanIEnumerable>

varcustQuery=

    fromcustincustomers

    groupcustbycust.CityintocustGroup

    wherecustGroup.Count()>2

    orderbycustGroup.Key

    selectcustGroup;

有关更多信息,请参见group子句(C#参考)。

联接

--------------------------------------------------------------------------------

联接运算创建数据源中没有显式建模的序列之间的关联。

例如,您可以执行联接来查找位于同一地点的所有客户和经销商。

在LINQ中,join子句始终针对对象集合而非直接针对数据库表运行。

C#复制

varinnerJoinQuery=

    fromcustincustomers

    joindistindistributorsoncust.Cityequalsdist.City

    selectnew{CustomerName=cust.Name,DistributorName=dist.Name};

在LINQ中,您不必像在SQL中那样频繁使用join,因为LINQ中的外键在对象模型中表示为包含项集合的属性。

例如,Customer对象包含Order对象的集合。

不必执行联接,只需使用点表示法访问订单:

使用LINQ进行数据转换(C#)

语言集成查询(LINQ)不仅可用于检索数据,

而且还是一个功能强大的数据转换工具。

通过使用LINQ查询,您可以将源序列用作输入,并采用多种方式修改它以创建新输出序列。

您可以通过排序和分组来修改序列本身,而不必修改元素本身。

但是,LINQ查询的最强大功能可能在于它能够创建新类型。

这一功能在

select

子句中实现。

例如,可以执行下列任务:

将多个输入序列合并到具有新类型的单个输出序列中。

创建其元素只包含源序列中的各个元素的一个或几个属性的输出序列。

创建其元素包含对源数据执行的操作结果的输出序列。

创建不同格式的输出序列。

例如,您可以将SQL行或文本文件的数据转换为XML。

这只是几个示例。

当然,可以采用多种方式将这些转换组合在同一查询中。

另外,一个查询的输出序列可用作新查询的输入序列。

将多个输入联接到一个输出序列

可以使用LINQ查询来创建包含多个输入序列的元素的输出序列。

下面的示例演示如何组合两个内存中的数据结构,但组合来自XML或SQL或数据集源的数据时可应用相同的原则。

假定下面两种类类型:

C#

classStudent

{

public

stringFirst{get;set;}

public

stringLast{get;set;}

public

intID{get;set;}

public

stringStreet{get;set;}

public

stringCity{get;set;}

publicListScores;

}

classTeacher

{

public

stringFirst{get;set;}

public

stringLast{get;set;}

public

intID{get;set;}

public

stringCity{get;set;}

}

下面的示例演示该查询:

C#

classDataTransformations

{

static

voidMain()

{

//Createthefirstdatasource.

Liststudents=newList()

{

newStudent{First="Svetlana",

Last="Omelchenko",

ID=111,

Street="123MainStreet",

City="Seattle",

Scores=newList{97,92,81,60}},

newStudent{First="Claire",

Last="O’Donnell",

ID=112,

Street="124MainStreet",

City="Redmond",

Scores=newList{75,84,91,39}},

newStudent{First="Sven",

Last="Mortensen",

ID=113,

Street="125MainStreet",

City="LakeCity",

Scores=newList{88,94,65,91}},

};

//Createtheseconddatasource.

Listteachers=newList()

{

newTeacher{First="Ann",Last="Beebe",ID=945,City="Seattle"},

newTeacher{First="Alex",Last="Robinson",ID=956,City="Redmond"},

newTeacher{First="Michiyo",Last="Sato",ID=972,City="Tacoma"}

};

//Createthequery.

varpeopleInSeattle=(fromstudentinstudents

wherestudent.City=="Seattle"

selectstudent.Last)

.Concat(fromteacherinteachers

whereteacher.City=="Seattle"

selectteacher.Last);

Console.WriteLine("ThefollowingstudentsandteachersliveinSeattle:

");

//Executethequery.

foreach(varpersoninpeopleInSeattle)

{

Console.WriteLine(person);

}

Console.WriteLine("Pressanykeytoexit.");

Console.ReadKey();

}

}

/*Output:

ThefollowingstudentsandteachersliveinSeattle:

Omelchenko

Beebe

*/

选择各个源元素的子集

选择源序列中的各个元素的子集有两种主要方法:

1.

若要只选择源元素的一个成员,请使用点运算。

在下面的示例中,假定Customer对象包含几个公共属性,其中包括名为City的字符串。

在执行此查询时,此查询将生成字符串输出序列。

other

varquery=fromcustinCustomers

selectcust.City;

2.

若要创建包含源元素的多个属性的元素,可以使用具有命名对象或匿名类型的对象初始值设定项。

下面的示例演示如何使用匿名类型来封装各个Customer元素的两个属性:

other

varquery=fromcustinCustomer

selectnew{Name=cust.Name,City=cust.City};

将内存中的对象转换为XML

通过LINQ查询,可以轻松地在内存中的数据结构、SQL数据库、ADO.NET数据集和XML流或文档之间转换数据。

下面的示例将内存中的数据结构中的对象转换为XML元素。

C#

classXMLTransform

{

static

voidMain()

{

//Createthedatasourcebyusingacollectioninitializer.

Liststudents=newList()

{

newStudent{First="Svetlana",Last="Omelchenko",ID=111,Scores=newList{97,92,81,60}},

newStudent{First="Claire",Last="O’Donnell",ID=112,Scores=newList{75,84,91,39}},

newStudent{First="Sven",Last="Mortensen",ID=113,Scores=newList{88,94,65,91}},

};

//Createthequery.

varstudentsToXML=newXElement("Root",

fromstudentinstudents

letx=String.Format("{0},{1},{2},{3}",student.Scores[0],

student.Scores[1],student.Scores[2],student.Scores[3])

select

newXElement("student",

newXElement("First",student.First),

newXElement("Last",student.Last),

newXElement("Scores",x)

)//end"student"

);//end"Root"

//Executethequery.

Console.WriteLine(studentsToXML);

//Keeptheconsoleopenindebugmode.

Console.WriteLine("Pressanykeytoexit.");

Console.ReadKey();

}

}

此代码生成下面的XML输出:

other

Svetlana

Omelchenko

97,92,81,60

Claire

O'Donnell

75,84,91,39

Sven

Mortensen

88,94,65,91

对源元素执行操作

输出序列可能不包含源序列的任何元素或元素属性。

输出可能是通过将源元素用作输入参数计算出的值的序列。

在执行下面这个简单查询时,此查询会输出一个字符串序列,该序列值表示根据double类型的元素的源序列进行的计算。

注意

如果查询将转换为某个其他域,则不支持在查询表达式中调用方法。

例如,不能在LINQtoSQL中调用一般C#方法,因为SQLServer没有该方法的上下文。

但是,可以将存储过程映射到方法,然后调用方法。

C#

classFormatQuery

{

static

voidMain()

{

//Datasource.

double[]radii={1,2,3};

//Query.

IEnumerablequery=

fromradinradii

selectString.Format("Area={0}",(rad*rad)*3.14);

//Queryexecution.

foreach(stringsinquery)

Console.WriteLine(s);

//Keeptheconsoleopenindebugmode.

Console.WriteLine("Pressanykeytoexit.");

Console.ReadKey();

}

}

/*Output:

Area=3.14

Area=12.56

Area=28.26

*/

LINQ和泛型类型(C#)

LINQ查询基于泛型类型,在.NETFramework的2.0版中引入了泛型类型。

您无需深入了解泛型即可开始编写查询。

但是,您可能需要了解两个基本概念:

1.

当您创建泛型集合类(如

List(OfT))的实例时,您将“T”替换为列表将包含的对象的类型。

例如,字符串列表表示为List,Customer对象列表表示为List

泛型列表是强类型的,且提供了比将其元素存储为

Object

的集合更多的好处。

如果您尝试将Customer添加到List,则会在编译时出现一条错误。

泛型集合易于使用的原因是您不必执行运行时类型强制转换。

2.

IEnumerable(OfT)

是一个接口,通过该接口,可以使用foreach语句来枚举泛型集合类。

泛型集合类支持

IEnumerable(OfT),就像非泛型集合类(如

ArrayList)支持

IEnumerable。

LINQ查询中的IEnumerable变量

LINQ查询变量类型化为

IEnumerable(OfT)

或派生类型,如

IQueryable(OfT)。

当您看到类型化为IEnumerable的查询变量时,这只意味着在执行该查询时,该查询将生成包含零个或多个Customer对象的序列。

C#

IEnumerablecustomerQuery=

fromcustincustomers

wherecust.City=="London"

selectcust;

foreach(CustomercustomerincustomerQuery)

{

Console.WriteLi

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

当前位置:首页 > 初中教育 > 语文

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2