有朋友反馈说我提供的sample不能编译。大概是版本的问题,可以到http://msdn2.microsoft.com/en-us/bb330936.aspx下载for beta1的版本。本节接着讲groupby。
上一节,我们讲了如何理解groupby返回的结果。本节会延这个思路阐述下去。先来看下面的例子
var
q
=
from
p
in
db.Products
group
p
by
p.CategoryID
into
g
select
new { CategoryID
=
g.
Key
, g };
如果,使用下面的语句。
var
q
=
from
p
in
db.Products
group
p
by
p.CategoryID
into
g
select
new { CategoryID
=
g.
Key
,GroupSet
=
g };
foreach
(var gp
in
q)
{
if (gp.CategoryID == 7)
{
foreach (var p in gp.GroupSet)
{
}
}
}
GroupBy中的Max, Min, Sum, Average,Count
如果,只想取每类产品中,单价为最大,用T-sql该怎么办呢?是不是要这么来写
SELECT
MAX
(
[
t0
]
.
[
UnitPrice
]
)
AS
[
MaxPrice
]
,
[
t0
]
.
[
CategoryID
]
FROM
[
dbo
]
.
[
Products
]
AS
[
t0
]
GROUP
BY
[
t0
]
.
[
CategoryID
]
var
q
=
from
p
in
db.Products
group
p
by
p.CategoryID
into
g
select
new {
g.
Key
,
MaxPrice
=
g.
Max
(p
=>
p.UnitPrice)
};
在这里,Max函数只对每个分组进行操作。我们来看看其结果
呀,这次,dlinq并没有把组里所有的纪录都取出来的吗。(请参考http://www.cnblogs.com/126/archive/2006/09/01/486388.html一文中的方法,配置sample.) dlinq只是简单做了统计,并返回结果。
每类产品中,单价为最小的,
var
q
=
from
p
in
db.Products
group
p
by
p.CategoryID
into
g
select
new {
g.
Key
,
MinPrice
=
g.
Min
(p
=>
p.UnitPrice)
};
var
q
=
from
p
in
db.Products
group
p
by
p.CategoryID
into
g
select
new {
g.
Key
,
AveragePrice
=
g.Average(p
=>
p.UnitPrice)
};
var
q
=
from
p
in
db.Products
group
p
by
p.CategoryID
into
g
select
new {
g.
Key
,
TotalPrice
=
g.
Sum
(p
=>
p.UnitPrice)
};
var
q
=
from
p
in
db.Products
group
p
by
p.CategoryID
into
g
select
new {
g.
Key
,
NumProducts
=
g.
Count
()
};
接着统计,同各类产品中,断货的产品数量。使用下面的语句。
var
q
=
from
p
in
db.Products
group
p
by
p.CategoryID
into
g
select
new {
g.
Key
,
NumProducts
=
g.
Count
(p
=>
p.Discontinued)
};
var
q
=
from
p
in
db.Products
group
p
by
p.CategoryID
into
g
where
g.
Count
()
>=
10
select
new {
g.
Key
,
ProductCount
=
g.
Count
()
};
SELECT
[
t1
]
.
[
CategoryID
]
,
[
t1
]
.
[
value2
]
AS
[
ProductCount
]
FROM
(
SELECT
COUNT
(
*
)
AS
[
value
]
,
COUNT
(
*
)
AS
[
value2
]
,
[
t0
]
.
[
CategoryID
]
FROM
[
dbo
]
.
[
Products
]
AS
[
t0
]
GROUP
BY
[
t0
]
.
[
CategoryID
]
)
AS
[
t1
]
WHERE
[
t1
]
.
[
value
]
>=
@p0
--
@p0: Input Int32 (Size = 0; Prec = 0; Scale = 0) [10]
--
Context: SqlProvider(Sql2005) Model: AttributedMetaModel Build: 2.0.20612.0
GroupBy操作中GroupBy的匿名类
在第一次谈到匿名类时,我们就提到不光Select操作可以使用匿名类,其他操作符也可以。但是,OrderBy不支持。请参考C#3.0入门系列(六)-之OrderBy操作
当用户既想按产品的分类,又想按供应商来做分组,该怎么办呢。这时,我们就该使用匿名类。
var
categories
=
from
p
in
db.Products
group
p
by
new { p.CategoryID, p.SupplierID }
into
g
select
new {g.
Key
, g};
在by后面,new出来一个匿名类。这里,Key其实质是一个类的对象,Key包含两个Property,一个是CategoryID,再一个是SupplierID ,要想取到具体CategoryID的值,需要g.Key.CategoryID,才能访问到。我们来看dlinq翻译的T-sql语句。
SELECT
[
t0
]
.
[
SupplierID
]
,
[
t0
]
.
[
CategoryID
]
FROM
[
dbo
]
.
[
Products
]
AS
[
t0
]
GROUP
BY
[
t0
]
.
[
CategoryID
]
,
[
t0
]
.
[
SupplierID
]
--
Context: SqlProvider(Sql2005) Model: AttributedMetaModel Build: 2.0.20612.0
先按CategoryID,再按SupplierID ,和匿名类中的循序一样。
最后一个例子。
var
categories
=
from
p
in
db.Products
group
p
by
new { Criterion
=
p.UnitPrice
>
10
}
into
g
select
g;
按产品单价是否大于10分类。其结果为两类,大于的是一类,小于及等于为另一类。好了,剩下的,大家自己多去领会。
本文详细介绍了 LINQ 中 GroupBy 操作的使用方法,包括如何利用 Select 的匿名类来包装分组结果,以及如何使用 Max、Min、Sum、Average 和 Count 等聚合函数对分组数据进行统计。
5157

被折叠的 条评论
为什么被折叠?



