LINQTOSQL.docx
《LINQTOSQL.docx》由会员分享,可在线阅读,更多相关《LINQTOSQL.docx(93页珍藏版)》请在冰豆网上搜索。
LINQTOSQL
Where操作
适用场景:
实现过滤,查询等功能。
说明:
与SQL命令中的Where作用相似,都是起到范围限定也就是过滤作用的,而判断条件就是它后面所接的子句。
Where操作包括3种形式,分别为简单形式、关系条件形式、First()形式。
下面分别用实例举例下:
1.简单形式:
例如:
使用where筛选在伦敦的客户
varq=
fromcindb.Customers
wherec.City=="London"
selectc;
再如:
筛选1994年或之后雇用的雇员:
varq=
fromeindb.Employees
wheree.HireDate>=newDateTime(1994,1,1)
selecte;
2.关系条件形式:
筛选库存量在订货点水平之下但未断货的产品:
varq=
frompindb.Products
wherep.UnitsInStock<=p.ReorderLevel&&!
p.Discontinued
selectp;
筛选出UnitPrice大于10或已停产的产品:
varq=
frompindb.Products
wherep.UnitPrice>10m||p.Discontinued
selectp;
下面这个例子是调用两次where以筛选出UnitPrice大于10且已停产的产品。
varq=
db.Products.Where(p=>p.UnitPrice>10m).Where(p=>p.Discontinued);
3.First()形式:
返回集合中的一个元素,其实质就是在SQL语句中加TOP
(1)。
简单用法:
选择表中的第一个发货方。
Shippershipper=db.Shippers.First();
元素:
选择CustomerID为“BONAP”的单个客户
Customercust=db.Customers.First(c=>c.CustomerID=="BONAP");
条件:
选择运费大于10.00的订单:
Orderord=db.Orders.First(o=>o.Freight>10.00M);
Select/Distinct操作符
适用场景:
o(∩_∩)o…查询呗。
说明:
和SQL命令中的select作用相似但位置不同,查询表达式中的select及所接子句是放在表达式最后并把子句中的变量也就是结果返回回来;延迟。
Select/Distinct操作包括9种形式,分别为简单用法、匿名类型形式、条件形式、指定类型形式、筛选形式、整形类型形式、嵌套类型形式、本地方法调用形式、Distinct形式。
1.简单用法:
这个示例返回仅含客户联系人姓名的序列。
varq=
fromcindb.Customers
selectc.ContactName;
注意:
这个语句只是一个声明或者一个描述,并没有真正把数据取出来,只有当你需要该数据的时候,它才会执行这个语句,这就是延迟加载(deferredloading)。
如果,在声明的时候就返回的结果集是对象的集合。
你可以使用ToList()或ToArray()方法把查询结果先进行保存,然后再对这个集合进行查询。
当然延迟加载(deferredloading)可以像拼接SQL语句那样拼接查询语法,再执行它。
2.匿名类型形式:
说明:
匿名类型是C#3.0中新特性。
其实质是编译器根据我们自定义自动产生一个匿名的类来帮助我们实现临时变量的储存。
匿名类型还依赖于另外一个特性:
支持根据property来创建对象。
比如,vard=new{Name="s"};编译器自动产生一个有property叫做Name的匿名类,然后按这个类型分配内存,并初始化对象。
但是vard=new{"s"};是编译不通过的。
因为,编译器不知道匿名类中的property的名字。
例如stringc="d";vard=new{c};则是可以通过编译的。
编译器会创建一个叫做匿名类带有叫c的property。
例如下例:
new{c,ContactName,c.Phone};ContactName和Phone都是在映射文件中定义与表中字段相对应的property。
编译器读取数据并创建对象时,会创建一个匿名类,这个类有两个属性,为ContactName和Phone,然后根据数据初始化对象。
另外编译器还可以重命名property的名字。
varq=
fromcindb.Customers
selectnew{c.ContactName,c.Phone};
上面语句描述:
使用SELECT和匿名类型返回仅含客户联系人姓名和电话号码的序列
varq=
fromeindb.Employees
selectnew
{
Name=e.FirstName+""+e.LastName,
Phone=e.HomePhone
};
上面语句描述:
使用SELECT和匿名类型返回仅含雇员姓名和电话号码的序列,并将FirstName和LastName字段合并为一个字段“Name”,此外在所得的序列中将HomePhone字段重命名为Phone。
varq=
frompindb.Products
selectnew
{
p.ProductID,
HalfPrice=p.UnitPrice/2
};
上面语句描述:
使用SELECT和匿名类型返回所有产品的ID以及HalfPrice(设置为产品单价除以2所得的值)的序列。
3.条件形式:
说明:
生成SQL语句为:
casewhenconditionthenelse。
varq=
frompindb.Products
selectnew
{
p.ProductName,
Availability=
p.UnitsInStock-p.UnitsOnOrder<0?
"OutOfStock":
"InStock"
};
上面语句描述:
使用SELECT和条件语句返回产品名称和产品供货状态的序列。
4.指定类型形式:
说明:
该形式返回你自定义类型的对象集。
varq=
fromeindb.Employees
selectnewName
{
FirstName=e.FirstName,
LastName=e.LastName
};
上面语句描述:
使用SELECT和已知类型返回雇员姓名的序列。
5.筛选形式:
说明:
结合where使用,起到过滤作用。
varq=
fromcindb.Customers
wherec.City=="London"
selectc.ContactName;
上面语句描述:
使用SELECT和WHERE返回仅含伦敦客户联系人姓名的序列。
6.shaped形式(整形类型):
说明:
其select操作使用了匿名对象,而这个匿名对象中,其属性也是个匿名对象。
varq=
fromcindb.Customers
selectnew{
c.CustomerID,
CompanyInfo=new{c.CompanyName,c.City,c.Country},
ContactInfo=new{c.ContactName,c.ContactTitle}
};
语句描述:
使用SELECT和匿名类型返回有关客户的数据的整形子集。
查询顾客的ID和公司信息(公司名称,城市,国家)以及联系信息(联系人和职位)。
7.嵌套类型形式:
说明:
返回的对象集中的每个对象DiscountedProducts属性中,又包含一个集合。
也就是每个对象也是一个集合类。
varq=
fromoindb.Orders
selectnew{
o.OrderID,
DiscountedProducts=
fromodino.OrderDetails
whereod.Discount>0.0
selectod,
FreeShippingDiscount=o.Freight
};
语句描述:
使用嵌套查询返回所有订单及其OrderID的序列、打折订单中项目的子序列以及免送货所省下的金额。
8.本地方法调用形式(LocalMethodCall):
这个例子在查询中调用本地方法PhoneNumberConverter将电话号码转换为国际格式。
varq=fromcindb.Customers
wherec.Country=="UK"||c.Country=="USA"
selectnew
{
c.CustomerID,
c.CompanyName,
Phone=c.Phone,
InternationalPhone=
PhoneNumberConverter(c.Country,c.Phone)
};
PhoneNumberConverter方法如下:
publicstringPhoneNumberConverter(stringCountry,stringPhone)
{
Phone=Phone.Replace("","").Replace(")",")-");
switch(Country)
{
case"USA":
return"1-"+Phone;
case"UK":
return"44-"+Phone;
default:
returnPhone;
}
}
下面也是使用了这个方法将电话号码转换为国际格式并创建XDocument
XDocumentdoc=newXDocument(
newXElement("Customers",fromcindb.Customers
wherec.Country=="UK"||c.Country=="USA"
select(newXElement("Customer",
newXAttribute("CustomerID",c.CustomerID),
newXAttribute("CompanyName",c.CompanyName),
newXAttribute("InterationalPhone",
PhoneNumberConverter(c.Country,c.Phone))
))));
9.Distinct形式:
说明:
筛选字段中不相同的值。
用于查询不重复的结果集。
生成SQL语句为:
SELECTDISTINCT[City]FROM[Customers]
varq=(
fromcindb.Customers
selectc.City)
.Distinct();
语句描述:
查询顾客覆盖的国家。
Count/Sum/Min/Max/Avg操作符
适用场景:
统计数据吧,比如统计一些数据的个数,求和,最小值,最大值,平均数。
Count
说明:
返回集合中的元素个数,返回INT类型;不延迟。
生成SQL语句为:
SELECTCOUNT(*)FROM
1.简单形式:
得到数据库中客户的数量:
varq=db.Customers.Count();
2.带条件形式:
得到数据库中未断货产品的数量:
varq=db.Products.Count(p=>!
p.Discontinued);
LongCount
说明:
返回集合中的元素个数,返回LONG类型;不延迟。
对于元素个数较多的集合可视情况可以选用LongCount来统计元素个数,它返回long类型,比较精确。
生成SQL语句为:
SELECTCOUNT_BIG(*)FROM
varq=db.Customers.LongCount();
Sum
说明:
返回集合中数值类型元素之和,集合应为INT类型集合;不延迟。
生成SQL语句为:
SELECTSUM(…)FROM
1.简单形式:
得到所有订单的总运费:
varq=db.Orders.Select(o=>o.Freight).Sum();
2.映射形式:
得到所有产品的订货总数:
varq=db.Products.Sum(p=>p.UnitsOnOrder);
Min
说明:
返回集合中元素的最小值;不延迟。
生成SQL语句为:
SELECTMIN(…)FROM
1.简单形式:
查找任意产品的最低单价:
varq=db.Products.Select(p=>p.UnitPrice).Min();
2.映射形式:
查找任意订单的最低运费:
varq=db.Orders.Min(o=>o.Freight);
3.元素:
查找每个类别中单价最低的产品:
varcategories=
frompindb.Products
grouppbyp.CategoryIDintog
selectnew{
CategoryID=g.Key,
CheapestProducts=
fromp2ing
wherep2.UnitPrice==g.Min(p3=>p3.UnitPrice)
selectp2
};
Max
说明:
返回集合中元素的最大值;不延迟。
生成SQL语句为:
SELECTMAX(…)FROM
1.简单形式:
查找任意雇员的最近雇用日期:
varq=db.Employees.Select(e=>e.HireDate).Max();
2.映射形式:
查找任意产品的最大库存量:
varq=db.Products.Max(p=>p.UnitsInStock);
3.元素:
查找每个类别中单价最高的产品:
varcategories=
frompindb.Products
grouppbyp.CategoryIDintog
selectnew{
g.Key,
MostExpensiveProducts=
fromp2ing
wherep2.UnitPrice==g.Max(p3=>p3.UnitPrice)
selectp2
};
Average
说明:
返回集合中的数值类型元素的平均值。
集合应为数字类型集合,其返回值类型为double;不延迟。
生成SQL语句为:
SELECTAVG(…)FROM
1.简单形式:
得到所有订单的平均运费:
varq=db.Orders.Select(o=>o.Freight).Average();
2.映射形式:
得到所有产品的平均单价:
varq=db.Products.Average(p=>p.UnitPrice);
3.元素:
查找每个类别中单价高于该类别平均单价的产品:
varcategories=
frompindb.Products
grouppbyp.CategoryIDintog
selectnew{
g.Key,
ExpensiveProducts=
fromp2ing
wherep2.UnitPrice>g.Average(p3=>p3.UnitPrice)
selectp2
};
Aggregate
说明:
根据输入的表达式获取聚合值;不延迟。
即是说:
用一个种子值与当前元素通过指定的函数来进行对比来遍历集合中的元素,符合条件的元素保留下来。
如果没有指定种子值的话,种子值默认为集合的第一个元素。
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,也就是