LINQ体验6LINQ to SQL语句之Join和Order By.docx

上传人:b****5 文档编号:8509555 上传时间:2023-01-31 格式:DOCX 页数:11 大小:36.81KB
下载 相关 举报
LINQ体验6LINQ to SQL语句之Join和Order By.docx_第1页
第1页 / 共11页
LINQ体验6LINQ to SQL语句之Join和Order By.docx_第2页
第2页 / 共11页
LINQ体验6LINQ to SQL语句之Join和Order By.docx_第3页
第3页 / 共11页
LINQ体验6LINQ to SQL语句之Join和Order By.docx_第4页
第4页 / 共11页
LINQ体验6LINQ to SQL语句之Join和Order By.docx_第5页
第5页 / 共11页
点击查看更多>>
下载资源
资源描述

LINQ体验6LINQ to SQL语句之Join和Order By.docx

《LINQ体验6LINQ to SQL语句之Join和Order By.docx》由会员分享,可在线阅读,更多相关《LINQ体验6LINQ to SQL语句之Join和Order By.docx(11页珍藏版)》请在冰豆网上搜索。

LINQ体验6LINQ to SQL语句之Join和Order By.docx

LINQ体验6LINQtoSQL语句之Join和OrderBy

Join操作

适用场景:

在我们表关系中有一对一关系,一对多关系,多对多关系等。

对各个表之间的关系,就用这些实现对多个表的操作。

说明:

在Join操作中,分别为Join(Join查询),SelectMany(Select一对多选择)和GroupJoin(分组Join查询)。

该扩展方法对两个序列中键匹配的元素进行innerjoin操作

SelectMany

说明:

我们在写查询语句时,如果被翻译成SelectMany需要满足2个条件。

1:

查询语句中没有join和into,2:

必须出现EntitySet。

在我们表关系中有一对一关系,一对多关系,多对多关系等,下面分别介绍一下。

1.一对多关系(1toMany):

varq=

fromcindb.Customers

fromoinc.Orders

wherec.City=="London"

selecto;

语句描述:

Customers与Orders是一对多关系。

即Orders在Customers类中以EntitySet形式出现。

所以第二个from是从c.Orders而不是db.Orders里进行筛选。

这个例子在From子句中使用外键导航选择伦敦客户的所有订单。

varq=

frompindb.Products

wherep.Supplier.Country=="USA"&&p.UnitsInStock==0

selectp;

语句描述:

这一句使用了p.Supplier.Country条件,间接关联了Supplier表。

这个例子在Where子句中使用外键导航筛选其供应商在美国且缺货的产品。

生成SQL语句为:

SELECT[t0].[ProductID],[t0].[ProductName],[t0].[SupplierID],

[t0].[CategoryID],[t0].[QuantityPerUnit],[t0].[UnitPrice],

[t0].[UnitsInStock],[t0].[UnitsOnOrder],[t0].[ReorderLevel],

[t0].[Discontinued]FROM[dbo].[Products]AS[t0]

LEFTOUTERJOIN[dbo].[Suppliers]AS[t1]ON

[t1].[SupplierID]=[t0].[SupplierID]

WHERE([t1].[Country]=@p0)AND([t0].[UnitsInStock]=@p1)

--@p0:

InputNVarChar(Size=3;Prec=0;Scale=0)[USA]

--@p1:

InputInt(Size=0;Prec=0;Scale=0)[0]

2.多对多关系(ManytoMany):

varq=

fromeindb.Employees

frometine.EmployeeTerritories

wheree.City=="Seattle"

selectnew

{

e.FirstName,

e.LastName,

et.Territory.TerritoryDescription

};

说明:

多对多关系一般会涉及三个表(如果有一个表是自关联的,那有可能只有2个表)。

这一句语句涉及Employees,EmployeeTerritories,Territories三个表。

它们的关系是1:

M:

1。

Employees和Territories没有很明确的关系。

语句描述:

这个例子在From子句中使用外键导航筛选在西雅图的雇员,同时列出其所在地区。

这条生成SQL语句为:

SELECT[t0].[FirstName],[t0].[LastName],[t2].[TerritoryDescription]

FROM[dbo].[Employees]AS[t0]CROSSJOIN[dbo].[EmployeeTerritories]

AS[t1]INNERJOIN[dbo].[Territories]AS[t2]ON

[t2].[TerritoryID]=[t1].[TerritoryID]

WHERE([t0].[City]=@p0)AND([t1].[EmployeeID]=[t0].[EmployeeID])

--@p0:

InputNVarChar(Size=7;Prec=0;Scale=0)[Seattle]

3.自联接关系:

varq=

frome1indb.Employees

frome2ine1.Employees

wheree1.City==e2.City

selectnew{

FirstName1=e1.FirstName,LastName1=e1.LastName,

FirstName2=e2.FirstName,LastName2=e2.LastName,

e1.City

};

语句描述:

这个例子在select子句中使用外键导航筛选成对的雇员,每对中一个雇员隶属于另一个雇员,且两个雇员都来自相同城市。

生成SQL语句为:

SELECT[t0].[FirstName]AS[FirstName1],[t0].[LastName]AS

[LastName1],[t1].[FirstName]AS[FirstName2],[t1].[LastName]AS

[LastName2],[t0].[City]FROM[dbo].[Employees]AS[t0],

[dbo].[Employees]AS[t1]WHERE([t0].[City]=[t1].[City])AND

([t1].[ReportsTo]=[t0].[EmployeeID])

GroupJoin

像上面所说的,没有join和into,被翻译成SelectMany,同时有join和into时,那么就被翻译为GroupJoin。

在这里into的概念是对其结果进行重新命名。

1.双向联接(Twowayjoin):

此示例显式联接两个表并从这两个表投影出结果:

varq=

fromcindb.Customers

joinoindb.Ordersonc.CustomerID

equalso.CustomerIDintoorders

selectnew

{

c.ContactName,

OrderCount=orders.Count()

};

说明:

在一对多关系中,左边是1,它每条记录为c(fromcindb.Customers),右边是Many,其每条记录叫做o(joinoindb.Orders),每对应左边的一个c,就会有一组o,那这一组o,就叫做orders,也就是说,我们把一组o命名为orders,这就是into用途。

这也就是为什么在select语句中,orders可以调用聚合函数Count。

在T-SQL中,使用其内嵌的T-SQL返回值作为字段值。

如图所示:

生成SQL语句为:

SELECT[t0].[ContactName],(

SELECTCOUNT(*)

FROM[dbo].[Orders]AS[t1]

WHERE[t0].[CustomerID]=[t1].[CustomerID]

)AS[OrderCount]

FROM[dbo].[Customers]AS[t0]

2.三向联接(Therewayjoin):

此示例显式联接三个表并分别从每个表投影出结果:

varq=

fromcindb.Customers

joinoindb.Ordersonc.CustomerID

equalso.CustomerIDintoords

joineindb.Employeesonc.City

equalse.Cityintoemps

selectnew

{

c.ContactName,

ords=ords.Count(),

emps=emps.Count()

};

生成SQL语句为:

SELECT[t0].[ContactName],(

SELECTCOUNT(*)

FROM[dbo].[Orders]AS[t1]

WHERE[t0].[CustomerID]=[t1].[CustomerID]

)AS[ords],(

SELECTCOUNT(*)

FROM[dbo].[Employees]AS[t2]

WHERE[t0].[City]=[t2].[City]

)AS[emps]

FROM[dbo].[Customers]AS[t0]

3.左外部联接(LeftOuterJoin):

此示例说明如何通过使用此示例说明如何通过使用DefaultIfEmpty()获取左外部联接。

在雇员没有订单时,DefaultIfEmpty()方法返回null:

varq=

fromeindb.Employees

joinoindb.Ordersoneequalso.Employeeintoords

fromoinords.DefaultIfEmpty()

selectnew

{

e.FirstName,

e.LastName,

Order=o

};

说明:

以Employees左表,Orders右表,Orders表中为空时,用null值填充。

Join的结果重命名ords,使用DefaultIfEmpty()函数对其再次查询。

其最后的结果中有个Order,因为fromoinords.DefaultIfEmpty()是对ords组再一次遍历,所以,最后结果中的Order并不是一个集合。

但是,如果没有fromoinords.DefaultIfEmpty()这句,最后的select语句写成selectnew{e.FirstName,e.LastName,Order=ords}的话,那么Order就是一个集合。

4.投影的Let赋值(Projectedletassignment):

说明:

let语句是重命名。

let位于第一个from和select语句之间。

这个例子从联接投影出最终“Let”表达式:

varq=

fromcindb.Customers

joinoindb.Ordersonc.CustomerID

equalso.CustomerIDintoords

letz=c.City+c.Country

fromoinords

selectnew

{

c.ContactName,

o.OrderID,

z

};

5.组合键(CompositeKey):

这个例子显示带有组合键的联接:

varq=

fromoindb.Orders

frompindb.Products

joindindb.OrderDetails

onnew

{

o.OrderID,

p.ProductID

}equals

new

{

d.OrderID,

d.ProductID

}

intodetails

fromdindetails

selectnew

{

o.OrderID,

p.ProductID,

d.UnitPrice

};

说明:

使用三个表,并且用匿名类来说明:

使用三个表,并且用匿名类来表示它们之间的关系。

它们之间的关系不能用一个键描述清楚,所以用匿名类,来表示组合键。

还有一种是两个表之间是用组合键表示关系的,不需要使用匿名类。

6.可为null/不可为null的键关系(Nullable/NonnullableKeyRelationship):

这个实例显示如何构造一侧可为null而另一侧不可为null的联接:

varq=

fromoindb.Orders

joineindb.Employees

ono.EmployeeIDequals

(int?

)e.EmployeeIDintoemps

fromeinemps

selectnew

{

o.OrderID,

e.FirstName

};

OrderBy操作

适用场景:

对查询出的语句进行排序,比如按时间排序等等。

说明:

按指定表达式对集合排序;延迟,:

按指定表达式对集合排序;延迟,默认是升序,加上descending表示降序,对应的扩展方法是OrderBy和OrderByDescending

1.简单形式

这个例子使用orderby按雇用日期对雇员进行排序:

varq=

fromeindb.Employees

orderbye.HireDate

selecte;

说明:

默认为升序

2.带条件形式

注意:

Where和OrderBy的顺序并不重要。

而在T-SQL中,Where和OrderBy有严格的位置限制。

varq=

fromoindb.Orders

whereo.ShipCity=="London"

orderbyo.Freight

selecto;

语句描述:

使用where和orderby按运费进行排序。

3.降序排序

varq=

frompindb.Products

orderbyp.UnitPricedescending

selectp;

4.ThenBy

语句描述:

使用复合的orderby对客户进行排序,进行排序:

varq=

fromcindb.Customers

orderbyc.City,c.ContactName

selectc;

说明:

按多个表达式进行排序,例如先按City排序,当City相同时,按ContactName排序。

这一句用Lambda表达式像这样写:

varq=

db.Customers

.OrderBy(c=>c.City)

.ThenBy(c=>c.ContactName).ToList();

在T-SQL中没有ThenBy语句,其依然翻译为OrderBy,所以也可以用下面语句来表达:

varq=

db.Customers

.OrderBy(c=>c.ContactName)

.OrderBy(c=>c.City).ToList();

所要注意的是,多个OrderBy操作时,级连方式是按逆序。

对于降序的,用相应的降序操作符替换即可。

varq=

db.Customers

.OrderByDescending(c=>c.City)

.ThenByDescending(c=>c.ContactName).ToList();

需要说明的是,OrderBy操作,不支持按type排序,也不支持匿名类。

比如

varq=

db.Customers

.OrderBy(c=>new

{

c.City,

c.ContactName

}).ToList();

会被抛出异常。

错误是前面的操作有匿名类,再跟OrderBy时,比较的是类别。

比如

varq=

db.Customers

.Select(c=>new

{

c.City,

c.Address

})

.OrderBy(c=>c).ToList();

如果你想使用OrderBy(c=>c),其前提条件是,前面步骤中,所产生的对象的类别必须为C#语言的基本类型。

比如下句,这里City为string类型。

varq=

db.Customers

.Select(c=>c.City)

.OrderBy(c=>c).ToList();

5.ThenByDescending

这两个扩展方式都是用在OrderBy/OrderByDescending之后的,第一个ThenBy/ThenByDescending扩展方法作为第二位排序依据,第二个ThenBy/ThenByDescending则作为第三位排序依据,以此类推

varq=

fromoindb.Orders

whereo.EmployeeID==1

orderbyo.ShipCountry,o.Freightdescending

selecto;

语句描述:

使用orderby先按发往国家再按运费从高到低的顺序对EmployeeID1的订单进行排序。

6.带GroupBy形式

varq=

frompindb.Products

grouppbyp.CategoryIDintog

orderbyg.Key

selectnew{

g.Key,

MostExpensiveProducts=

fromp2ing

wherep2.UnitPrice==g.Max(p3=>p3.UnitPrice)

selectp2

};

语句描述:

使用orderby、Max和GroupBy得出每种类别中单价最高的产品,并按CategoryID对这组产品进行排序。

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

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

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

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