LINQ标准查询操作符(二)——Join、GroupJoin、GroupBy、Concat、
四、联接操作符
联接是指将一个数据源对象与另一个数据源对象进行关联或者联合的操作。这两个数据源对象通过一个共同的值或者属性进行关联。
LINQ有两个联接操作符:Join和GroupJoin。
1. Join
Join操作符类似于T-SQL中的inner join,它将两个数据源相联接,根据两个数据源中相等的值进行匹配。例如,可以将产品表与产品类别表相联接,得到产品名称和与其相对应的类别名称。以下的代码演示了这一点:
//查询语法
var query =
(from p in db.Products
join c in db.Categories on p.CategoryID equals c.CategoryID
where p.CategoryID ==
select new { p.ProductID, p.ProductName, c.CategoryID, c.CategoryName }).ToList(); 生成的sql:
SELECT
[Extent1].[ProductID] AS [ProductID],
[Extent1].[ProductName] AS [ProductName],
[Extent2].[CategoryID] AS [CategoryID],
[Extent2].[CategoryName] AS [CategoryName]
FROM [dbo].[Products] AS [Extent1]
INNER JOIN [dbo].[Categories] AS [Extent2] ON [Extent1].[CategoryID] = [Extent2].[CategoryID]
WHERE ( = [Extent1].[CategoryID]) AND ([Extent1].[CategoryID] IS NOT NULL) //方法语法
var q =
db.Products
.Join
(
db.Categories,
p => p.CategoryID,
c => c.CategoryID,
(p, c) => new { p.ProductID, p.ProductName, c.CategoryID, c.CategoryName }
)
.Where(p => p.CategoryID == )
.ToList(); 生成的sql:
SELECT
[Extent1].[ProductID] AS [ProductID],
[Extent1].[ProductName] AS [ProductName],
[Extent2].[CategoryID] AS [CategoryID],
[Extent2].[CategoryName] AS [CategoryName]
FROM [dbo].[Products] AS [Extent1]
INNER JOIN [dbo].[Categories] AS [Extent2] ON [Extent1].[CategoryID] = [Extent2].[CategoryID]
WHERE 1 = [Extent2].[CategoryID]
以上代码为表述清晰加入了一个条件“where p.CategoryID == 1”,即仅返回产品类别ID为1的所有产品。
生成的sql语句略有不同。
2. GroupJoin
GroupJoin操作符常应用于返回“主键对象-外键对象集合”形式的查询,例如“产品类别-此类别下的所有产品”。以下的代码演示了这一点:
//查询语法
var query =
(from c in db.Categories
join p in db.Products on c.CategoryID equals p.CategoryID into r
select new
{
c.CategoryName,
Products = r
}).ToList();
//方法语法
var q =
db.Categories
.GroupJoin
(
db.Products,
c => c.CategoryID,
p => p.CategoryID,
(c, p) => new
{
c.CategoryName,
Products = p
}
)
.ToList(); 生成的sql:
SELECT
[Project1].[CategoryID] AS [CategoryID],
[Project1].[CategoryName] AS [CategoryName],
[Project1].[C1] AS [C1],
[Project1].[ProductID] AS [ProductID],
[Project1].[ProductName] AS [ProductName],
[Project1].[SupplierID] AS [SupplierID],
[Project1].[CategoryID1] AS [CategoryID1],
[Project1].[QuantityPerUnit] AS [QuantityPerUnit],
[Project1].[UnitPrice] AS [UnitPrice],
[Project1].[UnitsInStock] AS [UnitsInStock],
[Project1].[UnitsOnOrder] AS [UnitsOnOrder],
[Project1].[ReorderLevel] AS [ReorderLevel],
[Project1].[Discontinued] AS [Discontinued]
FROM ( SELECT
[Extent1].[CategoryID] AS [CategoryID],
[Extent1].[CategoryName] AS [CategoryName],
[Extent2].[ProductID] AS [ProductID],
[Extent2].[ProductName] AS [ProductName],
[Extent2].[SupplierID] AS [SupplierID],
[Extent2].[CategoryID] AS [CategoryID1],
[Extent2].[QuantityPerUnit] AS [QuantityPerUnit],
[Extent2].[UnitPrice] AS [UnitPrice],
[Extent2].[UnitsInStock] AS [UnitsInStock],
[Extent2].[UnitsOnOrder] AS [UnitsOnOrder],
[Extent2].[ReorderLevel] AS [ReorderLevel],
[Extent2].[Discontinued] AS [Discontinued],
CASE WHEN ([Extent2].[ProductID] IS NULL) THEN CAST(NULL AS int) ELSE END AS [C1]
FROM [dbo].[Categories] AS [Extent1]
LEFT OUTER JOIN [dbo].[Products] AS [Extent2] ON [Extent1].[CategoryID] = [Extent2].[CategoryID]
) AS [Project1]
ORDER BY [Project1].[CategoryID] ASC, [Project1].[C1] ASC
返回的结果为:
五、分组操作符
分组是根据一个特定的值将序列中的元素进行分组。LINQ只包含一个分组操作符:GroupBy。
下面的示例中使用了产品表,以CategoryID作为分组关键值,按照产品类别对产品进行了分组。
//查询语法
var query =
(from p in db.Products
group p by p.CategoryID).ToList();
//方法语法
var q =
db.Products
.GroupBy(p => p.CategoryID)
.ToList(); 生成的sql:
SELECT
[Project2].[C1] AS [C1],
[Project2].[CategoryID] AS [CategoryID],
[Project2].[C2] AS [C2],
[Project2].[ProductID] AS [ProductID],
[Project2].[ProductName] AS [ProductName],
[Project2].[SupplierID] AS [SupplierID],
[Project2].[CategoryID1] AS [CategoryID1],
[Project2].[QuantityPerUnit] AS [QuantityPerUnit],
[Project2].[UnitPrice] AS [UnitPrice],
[Project2].[UnitsInStock] AS [UnitsInStock],
[Project2].[UnitsOnOrder] AS [UnitsOnOrder],
[Project2].[ReorderLevel] AS [ReorderLevel],
[Project2].[Discontinued] AS [Discontinued]
FROM ( SELECT
[Distinct1].[CategoryID] AS [CategoryID],
AS [C1],
[Extent2].[ProductID] AS [ProductID],
[Extent2].[ProductName] AS [ProductName],
[Extent2].[SupplierID] AS [SupplierID],
[Extent2].[CategoryID] AS [CategoryID1],
[Extent2].[QuantityPerUnit] AS [QuantityPerUnit],
[Extent2].[UnitPrice] AS [UnitPrice],
[Extent2].[UnitsInStock] AS [UnitsInStock],
[Extent2].[UnitsOnOrder] AS [UnitsOnOrder],
[Extent2].[ReorderLevel] AS [ReorderLevel],
[Extent2].[Discontinued] AS [Discontinued],
CASE WHEN ([Extent2].[ProductID] IS NULL) THEN CAST(NULL AS int) ELSE END AS [C2]
FROM (SELECT DISTINCT
[Extent1].[CategoryID] AS [CategoryID]
FROM [dbo].[Products] AS [Extent1] ) AS [Distinct1]
LEFT OUTER JOIN [dbo].[Products] AS [Extent2] ON ([Distinct1].[CategoryID] = [Extent2].[CategoryID]) OR (([Distinct1].[CategoryID] IS NULL) AND ([Extent2].[CategoryID] IS NULL))
) AS [Project2]
ORDER BY [Project2].[CategoryID] ASC, [Project2].[C2] ASC
执行GroupBy得到的序列中包含的元素类型为IGrouping<TKey, T>,其Key属性代表了分组时使用的关键值,遍历IGrouping<TKey, T>元素可以读取到每一个T类型。在此示例中,对应的元素类型为IGrouping<int, Products>,其Key属性即为类别ID,遍历它可以读取到每一个产品对象。
六、串联操作符
串联是一个将两个集合联接在一起的过程。在LINQ中,这个过程通过Concat操作符来实现。
在下面的示例中,将会把类别名称串联在产品名称之后:
//方法语法
var q =
db.Products
.Select(p => p.ProductName)
.Concat
(
db.Categories.Select(c => c.CategoryName)
)
.ToList(); 生成的sql: SELECT
[UnionAll1].[ProductName] AS [C1]
FROM (SELECT
[Extent1].[ProductName] AS [ProductName]
FROM [dbo].[Products] AS [Extent1]
UNION ALL
SELECT
[Extent2].[CategoryName] AS [CategoryName]
FROM [dbo].[Categories] AS [Extent2]) AS [UnionAll1]
返回结果77+8=85
LINQ标准查询操作符(二)——Join、GroupJoin、GroupBy、Concat、的更多相关文章
- Linq 标准查询操作符三
本文介绍了LINQ标准查询操作符.没有这些操作符,LINQ就不会存在.本文为理解这些操作符的功能提供了很好的基础.了解它们将会很有帮助,因为LINQ的各种Provider都是基于这些操作符来完成各自丰 ...
- LINQ 标准查询操作符
本文介绍了LINQ标准查询操作符.没有这些操作符,LINQ就不会存在.本文为理解这些操作符的功能提供了很好的基础.了解它们将会很有帮助,因为LINQ的各种Provider都是基于这些操作符来完成各自丰 ...
- LINQ标准查询操作符详解(转)
一. 关于LINQ LINQ 英文全称是“Language-Integrated Query”,中文为“语言集成查询”,它是微软首席架构师.Delphi 之父和C# 之父——Anders ...
- LINQ标准查询操作符(三)——Aggregate、Average、Distinct、Except、Intersect、Union、Empty、DefaultIfEmpty、Range、Repeat
七.聚合操作符 聚合函数将在序列上执行特定的计算,并返回单个值,如计算给定序列平均值.最大值等.共有7种LINQ聚合查询操作符:Aggregate.Average.Count.LongCount.Ma ...
- 【LINQ标准查询操作符总结】之聚合操符
C# 中的LINQ 提供了两种操作方式,查询表达式和查询操作符,所有的查询表达式都有对应的查操作符类替代,查询表达式有点“类” SQL,在代码中写SQL,总觉得不够“优雅”,使用查询操作符就显得“优 ...
- LINQ标准查询操作符(四) —AsEnumerable,Cast,OfType,ToArray,ToDictionary,ToList,ToLookup,First,Last,ElementAt
十.转换操作符 转换操作符是用来实现将输入对象的类型转变为序列的功能.名称以“As”开头的转换方法可更改源集合的静态类型但不枚举(延迟加载)此源集合.名称以“To”开头的方法可枚举(即时加载)源集合并 ...
- Linq标准查询操作符
Linq的出现让代码简洁了不少.之前在项目中基本都在使用它,但是没有完整的整理过,今天借这个周末,将其进行整理,方便后期对其的使用.Linq的操作可以分为聚合,连接,转换,元素操作符,相等操作,生成 ...
- LINQ标准查询操作符(五)
十二.相等操作符 如果两个序列的对应元素相等且这两个序列具有相同数量的元素,则视这两个序列相等. SequenceEqual方法通过并行地枚举两个数据源并比较相应元素来判断两个序列是否相等.如果两个序 ...
- LINQ标准查询操作符(一)——select、SelectMany、Where、OrderBy、OrderByDescending、ThenBy、ThenByDescending和Reverse
一.投影操作符 1. Select Select操作符对单个序列或集合中的值进行投影.下面的示例中使用select从序列中返回Employee表的所有列: //查询语法 var query = fro ...
随机推荐
- asp.net页面过滤所有换行符和多余空格
不知道大家注意到了没有,Google和Baidu网页的HTML源代码是混合在一起的.HTML代码混合在一起,出发点是为了减小网页体积,从而加快网页加载速度. 写个函数把网页HTML源代码的换行符和空格 ...
- ssh: Could not resolve hostname gitcafe.com: nodename nor servname provided, or not known
今天 git push 的时候报如下错误: ssh: Could not resolve hostname gitcafe.com: nodename nor servname provided, o ...
- LEFT JOIN、Right、Full后ON和WHERE的区别
今天在工作的时候碰到了一个问题,A表B表left join后在on后面关于A表的条件过滤语句没起到我想要的过滤作用,还是对左连接等理解的不够呀. SELECT * FROM student; SELE ...
- cocos2d-x 开启深度测试验 实现 遮挡
CCDirector::sharedDirector()->setDepthTest(true); spr->setVertexZ(xxx);
- 【温故知新】C#委托delegate
在c#的学习过程中,学到委托与事件总会迷糊一段时间,迷糊过后自然而就似懂非懂了~,所以最近我打算把以前所学的迷糊过的知识总结,温故知新,总结记录下来. 首先,我们来看一下msdn对委托的定义: del ...
- C++获取进程号及窗口
#include <TlHelp32.h> //根据进程名获取进程ID BOOL GetPidByProcessName(TCHAR *pProcess, DWORD*dwPid) { H ...
- 大数据导入Excel
在平时的项目中,将数据导出到Excel的需求是很常见的,在此对一些常见的方法做以总结,并提供一种大数据量导出的实现. OLEDB 使用OLEDB可以很方便导出Excel,思路很简单,处理时将Exc ...
- Linux setjmp longjmp
/********************************************************************* * Linux setjmp longjmp * 说明: ...
- 20160128.CCPP体系详解(0007天)
以下内容有所摘取,进行了某些整理和补充 论浮点数的存储原理:float浮点数与double浮点数的二进制存储原理–>阶码 浮点数转二进制 1.整数int类型和浮点数float类型都是占用4个字节 ...
- setTimeout/setInterval
//使用 setTimeout 时需注意,当该代码执行时,JS 会立即编译函数第一个参数“code” //所以该函数的第一个参数应该为:需要编译的代码.或者一个函数 //例1:setTimeout(& ...