LINQ to SQL语句之Group By/Having和Exists/In/Any/All/Contains

1.Group By/Having操作符

适用场景:分组数据,为我们查找数据缩小范围。

说明:分配并返回对传入参数进行分组操作后的可枚举对象。分组;延迟

1.简单形式:

var q =
from p in db.Products
group p by p.CategoryID into g
select g;

语句描述:使用Group By按CategoryID划分产品。  

说明:from p in db.Products 表示从表中将产品对象取出来。group p by p.CategoryID into g表示对p按CategoryID字段归类。其结果命名为g,一旦重新命名,p的作用域就结束了,所以,最后select时,只能select g。当然,也不必重新命名可以这样写:

var q =
from p in db.Products
group p by p.CategoryID;

如果想遍历某类别中所有记录,这样:

foreach (var gp in q)
{
if (gp.Key == 2)
{
foreach (var item in gp)
{
//do something
}
}
}

2.Select匿名类:

var q =
from p in db.Products
group p by p.CategoryID into g
select new { CategoryID = g.Key, g };

说明:在这句LINQ语句中,有2个property:CategoryID和g。这个匿名类,其实质是对返回结果集重新进行了包装。把g的property封装成一个完整的分组。

如果想遍历某匿名类中所有记录,要这么做:

foreach (var gp in q)
{
if (gp.CategoryID == 2)
{
foreach (var item in gp.g)
{
//do something
}
}
}

3.最大值

var q =
from p in db.Products
group p by p.CategoryID into g
select new {
g.Key,
MaxPrice = g.Max(p => p.UnitPrice)
};

语句描述:使用Group By和Max查找每个CategoryID的最高单价。

说明:先按CategoryID归类,判断各个分类产品中单价最大的Products。取出CategoryID值,并把UnitPrice值赋给MaxPrice。

4.最小值

var q =
from p in db.Products
group p by p.CategoryID into g
select new {
g.Key,
MinPrice = g.Min(p => p.UnitPrice)
};

语句描述:使用Group By和Min查找每个CategoryID的最低单价。

说明:先按CategoryID归类,判断各个分类产品中单价最小的Products。取出CategoryID值,并把UnitPrice值赋给MinPrice。

5.平均值

var q =
from p in db.Products
group p by p.CategoryID into g
select new {
g.Key,
AveragePrice = g.Average(p => p.UnitPrice)
};

语句描述:使用Group By和Average得到每个CategoryID的平均单价。

说明:先按CategoryID归类,取出CategoryID值和各个分类产品中单价的平均值。

6.求和

var q =
from p in db.Products
group p by p.CategoryID into g
select new {
g.Key,
TotalPrice = g.Sum(p => p.UnitPrice)
};

语句描述:使用Group By和Sum得到每个CategoryID 的单价总计。

说明:先按CategoryID归类,取出CategoryID值和各个分类产品中单价的总和。

7.计数

var q =
from p in db.Products
group p by p.CategoryID into g
select new {
g.Key,
NumProducts = g.Count()
};

语句描述:使用Group By和Count得到每个CategoryID中产品的数量。

说明:先按CategoryID归类,取出CategoryID值和各个分类产品的数量。

8.带条件计数

var q =
from p in db.Products
group p by p.CategoryID into g
select new {
g.Key,
NumProducts = g.Count(p => p.Discontinued)
};

语句描述:使用Group By和Count得到每个CategoryID中断货产品的数量。

说明:先按CategoryID归类,取出CategoryID值和各个分类产品的断货数量。 Count函数里,使用了Lambda表达式,Lambda表达式中的p,代表这个组里的一个元素或对象,即某一个产品。

9.Where限制

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()
};

语句描述:根据产品的―ID分组,查询产品数量大于10的ID和产品数量。这个示例在Group By子句后使用Where子句查找所有至少有10种产品的类别。

说明:在翻译成SQL语句时,在最外层嵌套了Where条件

10.多列(Multiple Columns)

var categories =
from p in db.Products
group p by new
{
p.CategoryID,
p.SupplierID
}
into g
select new
{
g.Key,
g
};

语句描述:使用Group By按CategoryID和SupplierID将产品分组。

说明: 既按产品的分类,又按供应商分类。在by后面,new出来一个匿名类。这里,Key其实质是一个类的对象,Key包含两个Property:CategoryID、SupplierID。用g.Key.CategoryID可以遍历CategoryID的值。

11.表达式(Expression)

var categories =
from p in db.Products
group p by new { Criterion = p.UnitPrice > 10 } into g
select g;

语句描述:使用Group By返回两个产品序列。第一个序列包含单价大于10的产品。第二个序列包含单价小于或等于10的产品。

说明:按产品单价是否大于10分类。其结果分为两类,大于的是一类,小于及等于为另一类。

Exists/In/Any/All/Contains操作符

适用场景:用于判断集合中元素,进一步缩小范围。

Any

说明:用于判断集合中是否有元素满足某一条件;不延迟。(若条件为空,则集合只要不为空就返回True,否则为False)。有2种形式,分别为简单形式和带条件形式。

1.简单形式:

仅返回没有订单的客户:

var q =
from c in db.Customers
where !c.Orders.Any()
select c;

生成SQL语句为:

SELECT [t0].[CustomerID], [t0].[CompanyName], [t0].[ContactName],
[t0].[ContactTitle], [t0].[Address], [t0].[City], [t0].[Region],
[t0].[PostalCode], [t0].[Country], [t0].[Phone], [t0].[Fax]
FROM [dbo].[Customers] AS [t0]
WHERE NOT (EXISTS(
SELECT NULL AS [EMPTY] FROM [dbo].[Orders] AS [t1]
WHERE [t1].[CustomerID] = [t0].[CustomerID]
))

  

2.带条件形式:

仅返回至少有一种产品断货的类别:

var q =
from c in db.Categories
where c.Products.Any(p => p.Discontinued)
select c;

生成SQL语句为:

SELECT [t0].[CategoryID], [t0].[CategoryName], [t0].[Description],
[t0].[Picture] FROM [dbo].[Categories] AS [t0]
WHERE EXISTS(
SELECT NULL AS [EMPTY] FROM [dbo].[Products] AS [t1]
WHERE ([t1].[Discontinued] = 1) AND
([t1].[CategoryID] = [t0].[CategoryID])
)

All

说明:用于判断集合中所有元素是否都满足某一条件;不延迟

1.带条件形式

var q =
from c in db.Customers
where c.Orders.All(o => o.ShipCity == c.City)
select c;

语句描述:这个例子返回所有订单都运往其所在城市的客户或未下订单的客户。

Contains

说明:用于判断集合中是否包含有某一元素;不延迟。它是对两个序列进行连接操作的。

string[] customerID_Set =
new string[] { "AROUT", "BOLID", "FISSA" };
var q = (
from o in db.Orders
where customerID_Set.Contains(o.CustomerID)
select o).ToList();

语句描述:查找"AROUT", "BOLID" 和 "FISSA" 这三个客户的订单。 先定义了一个数组,在LINQ to SQL中使用Contains,数组中包含了所有的CustomerID,即返回结果中,所有的CustomerID都在这个集合内。也就是in。 你也可以把数组的定义放在LINQ to SQL语句里。比如:

var q = (
from o in db.Orders
where (
new string[] { "AROUT", "BOLID", "FISSA" })
.Contains(o.CustomerID)
select o).ToList();

Not Contains则取反:

var q = (
from o in db.Orders
where !(
new string[] { "AROUT", "BOLID", "FISSA" })
.Contains(o.CustomerID)
select o).ToList();

1.包含一个对象:

var order = (from o in db.Orders
where o.OrderID == 10248
select o).First();
var q = db.Customers.Where(p => p.Orders.Contains(order)).ToList();
foreach (var cust in q)
{
foreach (var ord in cust.Orders)
{
//do something
}
}

语句描述:这个例子使用Contain查找哪个客户包含OrderID为10248的订单。

2.包含多个值:

string[] cities =
new string[] { "Seattle", "London", "Vancouver", "Paris" };
var q = db.Customers.Where(p=>cities.Contains(p.City)).ToList();

语句描述:这个例子使用Contains查找其所在城市为西雅图、伦敦、巴黎或温哥华的客户。

总结一下这篇我们说明了以下语句:

Group By/Having 分组数据;延迟
Any 用于判断集合中是否有元素满足某一条件;不延迟
All 用于判断集合中所有元素是否都满足某一条件;不延迟
Contains 用于判断集合中是否包含有某一元素;不延迟

LINQ学习之旅 (四)的更多相关文章

  1. Linq学习之旅——LINQ查询表达式

    1. 概述 2. from子句 3. where子句 4. select子句 5. group子句 6. into子句 7. 排序子句 8. let子句 9. join子句 10. 小结 1. 概述 ...

  2. LINQ学习之旅(六)

    Insert/Update/Delete操作 插入(Insert) 1.简单形式 说明:new一个对象,使用InsertOnSubmit方法将其加入到对应的集合中,使用SubmitChanges()提 ...

  3. LINQ学习之旅(五)

    Union All/Union/Intersect操作和Top/Bottom操作和Paging操作和SqlMethods操作 Union All/Union/Intersect操作 适用场景:对两个集 ...

  4. LINQ学习之旅(三)

    Linq to Sql语句之Join和Order By Join操作 适用场景:在我们表关系中有一对一关系,一对多关系,多对多关系等.对各个表之间的关系,就用这些实现对多个表的操作. 说明:在Join ...

  5. LINQ学习之旅(二)

    一:查询表达式(LINQ)简介 LINQ是Language Integrated Query的简称,它是集成在.NET编程语言中的一种特性.已成为编程语言的一个组成部分,在编写程序时可以得到很好的编译 ...

  6. LINQ学习之旅 C#3.0新特性(一)

    一:C#3.0新语言的特性 自动属性(Auto-Implemented Properties) 隐含类型局部变量(Local Variable Type Inference) 匿名类型(Anonymo ...

  7. [原创] zabbix学习之旅四:mail客户端安装

    相信大家使用zabbix的最主要目的就是当被监控机器发生故障时,能通过zabbix获得第一时间的报警提醒.zabbix常用的报警媒介有email,短信,jabber和脚本,这其中脚本类型最为灵活,尤其 ...

  8. Spring学习之旅(四)--高级装配Bean

    条件化 bean 有时候我们要满足某种情况才将bean 初始化放入容器中. 基于环境初始化不同的 bean 1.申明接口并创建两个实现类 public interface Teacher { void ...

  9. WCF学习之旅—实现支持REST客户端应用(二十四)

    WCF学习之旅—实现REST服务(二十二) WCF学习之旅—实现支持REST服务端应用(二十三) 在上二篇文章中简单介绍了一下RestFul与WCF支持RestFul所提供的方法,及创建一个支持RES ...

随机推荐

  1. weblogic11g 修改密码和重置密码【原】

    修改密码 知道密码的情况下,可参考该链接 http://www.cnblogs.com/may12138/p/6022946.html 或 http://www.cnblogs.com/lsdb/p/ ...

  2. C#星夜拾遗之delegate示例

    概念 delegate即委托.如果你使用过C++或者js中的回调函数,你会更容易明白一些.在异步操作中常常使用回调函数,例如在Ajax中,当HttpRequest执行异步请求时,就需要有一个状态改变时 ...

  3. Cmder-控制台模拟器

    Cmder是一个软件包,由于在Windows上缺少漂亮的控制台模拟器而纯粹受挫. 它基于令人惊叹的软件,并采用Monokai配色方案和自定义快速布局,从一开始就看起来很性感. 首先,展示一下界面,和W ...

  4. EntityFramework用法探索(八)事务处理

    使用 前文中描述的Retail示例 ,在Customer对象的Mapping中设置Name属性:我们构造一个有效的Customer对象,再构造一个无效的Name属性为空的对象. DomainModel ...

  5. MyBatis学习-入门

    eclipse + jdk 1.8 + mybatis 1.数据库准备 安装mysql数据库,建立数据库test,在test库下建立测试的表 CREATE TABLE `t_user` ( `id` ...

  6. transform 图标旋转,IE8、IE7不兼容

    要将图标旋转,只需使用transform的rotate以及transition即可完成旋转的动画效果.ease 规定慢速开始,然后变快,然后慢速结束的过渡效果;   ease-in 规定以慢速开始的过 ...

  7. Java 注解 (Annotation)你可以这样学

    注解语法 因为平常开发少见,相信有不少的人员会认为注解的地位不高.其实同 classs 和 interface 一样,注解也属于一种类型.它是在 Java SE 5.0 版本中开始引入的概念. 注解的 ...

  8. LaTeX 对齐问题

    一.一行文本对齐 \leftline{左对齐} \centerline{居中} \rightline{右对齐} 二.多行文本或段落对齐 左对齐 \begin{flushleft}...\end{flu ...

  9. LogParse-Windows系统日志分析

    Windows系统日志分析 一.前言 本文将对常见的日志类型,利用微软日志分析工具(LogParser)结合已经掌握的恶意代码分析Windows系统日志,关联出系统的异常. 数据来源于Windows的 ...

  10. gpio_request 原形代码【转】

    转自:http://blog.csdn.net/maopig/article/details/7428561 其原型为 int gpio_request(unsigned gpio, const ch ...