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 ...
随机推荐
- oracle教程:PLSQL常用方法汇总
oracle教程:PLSQL常用方法汇总 在SQLPLUS下,实现中-英字符集转换alter session set nls_language='AMERICAN';alter session set ...
- iconv字符编码转换
转自 http://blog.csdn.net/langresser_king/article/details/7459367 iconv(http://www.gnu.org/software/li ...
- CSS之弧形阴影
简述 网页上经常会出现一些弧形的阴影效果,看起来很漂亮,下面我们来讲述下如何用CSS来实现一个弧形阴影. 简述 阴影 效果 注释 标题 效果 源码 合并 效果 源码 阴影 效果 首先实现一个简单的阴影 ...
- 编写jquery插件的分享
一.类级别($.extend) 类级别你可以理解为拓展jquery类,最明显的例子是$.ajax(...),相当于静态方法. 开发扩展其方法时使用$.extend方法,即jQuery.extend(o ...
- 在view中常见的四种方法的使用场合
四种方法,使view创建好里面就有东西:[1.init 2.initWithFrame使用代码创建的时候.(从文件创建的时候不一定调用:1.init 2.initWithFrame这两个方法) 3 ...
- (转载)目前最细致清晰的NSDictionary以及NSMutableDictionary用法总结
文章转载自:http://www.cnblogs.com/wengzilin/archive/2012/03/15/2397712.html 做过Java语言 或者 C语言 开发的朋友应该很清楚 关键 ...
- SQL语句方法语法总结(二)
1.给表插入数据. (1)INSERT INTO TBL_NAME VALUES (VALUE_1,VALUE_2,...) (2)INSERT INTO TBL_NAME (COL_1,COL_2, ...
- 移植linux(1)
硬件环境:TQ2440 软件环境:linux-2.6.30.4 下载源码:ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.30.4.tar ...
- (转) Python Generators(生成器)——yield关键字
http://blog.csdn.net/scelong/article/details/6969276 生成器是这样一个函数,它记住上一次返回时在函数体中的位置.对生成器函数的第二次(或第 n 次) ...
- swun 1612 合并果子
//思路:这题思路似乎很简单,每次取出最小的两个堆合并, //但是由于数据太大,不能采取每次进行排序的方式,所以 //想到用优先队列,以数据小的优先级更高为标准,但是 //优先队列中的数据默认情况 ...