[C#] LINQ之Join与GroupJoin
声明:本文为www.cnc6.cn原创,转载时请注明出处,谢谢!
一、编写Person与City类,如下:
- class Person
- {
- public int CityID { set; get; }
- public string Name { set; get; }
- }
- class City
- {
- public int ID { set; get; }
- public string Name { set; get; }
- }
二、为以上两个类建立一些数据,存储于persons与cities中,如下:
- Person[] persons = new Person[]
- {
- new Person{ CityID = , Name = "ABC" },
- new Person{ CityID = , Name = "EFG" },
- new Person{ CityID = , Name = "HIJ" },
- new Person{ CityID = , Name = "KLM" },
- new Person{ CityID = , Name = "NOP" },
- new Person{ CityID = , Name = "QRS" },
- new Person{ CityID = , Name = "TUV" }
- };
- City[] cities = new City[]
- {
- new City{ ID = ,Name = "Guangzhou" },
- new City{ ID = ,Name = "Shenzhen" },
- new City{ ID = ,Name = "Beijing" },
- new City{ ID = ,Name = "Shanghai" }
- };
三、Join第一种用法:
- public static IEnumerable<TResult> Join<TOuter, TInner, TKey, TResult>(this IEnumerable<TOuter> outer, IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector, Func<TInner, TKey> innerKeySelector, Func<TOuter, TInner, TResult> resultSelector);
官方释义:基于匹配键对两个序列的元素进行关联。使用默认的相等比较器对键进行比较。
这个与数据库中的INNER JOIN很类似,就是使用一个键(TKey)将两个集合关联起来,并对这两个集合的元素进行选择,作为结果输出。
1、数据源本身为outer,需要作Join连接的集合为inner;
2、选择一个outer内的一个元素,作为输入参数,并输出一个基于outer的键值;
3、选择一个inner内的一个元素,作为输入参数,并输出一个基于inner的键值;
4、将基于outer的键值与inner的键值作为输入参数,并输出一个自己定义类型的结果选择器;
5、返回的结果就是自己定义类型的集合。
编写客户端试验代码:
- var result = persons.Join(cities, p => p.CityID, c => c.ID, (p, c) => new { PersonName = p.Name, CityName = c.Name});
- foreach(var item in result)
- {
- Console.WriteLine($"{item.PersonName},{item.CityName}");
- }
从以上可以看出,persons为outer集合,cities为inner集合,p.CityID为outer的键值,c.ID为inner的键值,Join就是将persons内CityID与cities内ID相等性连接起来,并将persons内的每个元素及cities内的每个元素作为输入参数,从从选择自己想要的数据,如自己定义的匿名类型。
因为persons内CityID为5的城市编号不存在与cIties内,因此输出结果不会含Name为“TUV”的信息。
输出结果如下:
其等价的LINQ语句为:
- var result = from p in persons
- join c in cities on p.CityID equals c.ID
- select new { PersonName = p.Name, CityName = c.Name };
四、Join第二种用法:
- public static IEnumerable<TResult> Join<TOuter, TInner, TKey, TResult>(this IEnumerable<TOuter> outer, IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector, Func<TInner, TKey> innerKeySelector, Func<TOuter, TInner, TResult> resultSelector, IEqualityComparer<TKey> comparer);
官方释义:基于匹配键对两个序列的元素进行关联。使用指定的IEqualityComparer<TKey> 对键进行比较。
以上与Join第一种方法无非就是多一个IEqualityComparer<TKey>,如果使用一个继承于IEqualityComparer<TKey>的类初始化comparer,它就会使用该类对对TOuter.TKey及TInner.TKey进行相等性比较,判断是否进行连接,并输出自己定义的类型集合。
五、GroupJoin第一种方法:
- public static IEnumerable<TResult> GroupJoin<TOuter, TInner, TKey, TResult>(this IEnumerable<TOuter> outer, IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector, Func<TInner, TKey> innerKeySelector, Func<TOuter, IEnumerable<TInner>, TResult> resultSelector);
官方释义: 基于键相等对两个序列的元素进行关联并对结果进行分组。使用默认的相等比较器对键进行比较。
这个与数据库的LEFT OUTER JOIN很类似。与Join的区别就是:GroupJoin内resultSelector的输入参数从TInner单个元素编程IEnumerable<TInner>元素集合,其他保持不变。用法与Join差不多,它也是基于TOuter.TKey及TInner.TKey的连接。
编写客户端试验代码:
- var result = persons.GroupJoin(cities, p => p.CityID, c => c.ID, (p, cs) => new { PersonName = p.Name, Citys = cs });
- foreach (var item in result)
- {
- Console.Write($"{item.PersonName}\t");
- foreach (var city in item.Citys)
- {
- Console.Write($"{city.Name}");
- }
- Console.WriteLine();
- }
这个输出会将Name为“TUV”的名字输出,但其城市却是空的,原因就是在cities找不到编号为5的City信息。
输出结果如下:
其等价的LINQ语句为:
- var result = from p in persons
- join c in cities on p.CityID equals c.ID into cs
- select new { PersonName = p.Name, Citys = cs };
六、GroupJoin第二种方法:
- public static IEnumerable<TResult> GroupJoin<TOuter, TInner, TKey, TResult>(this IEnumerable<TOuter> outer, IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector, Func<TInner, TKey> innerKeySelector, Func<TOuter, IEnumerable<TInner>, TResult> resultSelector, IEqualityComparer<TKey> comparer);
官方释义:基于键相等对两个序列的元素进行关联并对结果进行分组。使用指定的IEqualityComparer<TKey>对键进行比较。
这个与Join第二种方法类似,这里不再进行讲述。
[C#] LINQ之Join与GroupJoin的更多相关文章
- LINQ之 Join 与 GroupJoin
声明:本文为www.cnc6.cn原创,转载时请注明出处,谢谢! 一.编写Person与City类,如下: class Person { public int CityID { set; get; } ...
- LINQ标准查询操作符(二)——Join、GroupJoin、GroupBy、Concat、
四.联接操作符 联接是指将一个数据源对象与另一个数据源对象进行关联或者联合的操作.这两个数据源对象通过一个共同的值或者属性进行关联. LINQ有两个联接操作符:Join和GroupJoin. 1. J ...
- [C#]使用Join与GroupJoin将两个集合进行关联与分组
本文为原创文章.源代码为原创代码,如转载/复制,请在网页/代码处明显位置标明原文名称.作者及网址,谢谢! 本文使用的开发环境是VS2017及dotNet4.0,写此随笔的目的是给自己及新开发人员作为参 ...
- [C#] LINQ之SelectMany和GroupJoin
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...
- C#中使用Join与GroupJoin将两个集合进行关联与分组
转自:https://www.cnblogs.com/cncc/p/7985843.html 对于Join的用法说明如下: 语法: public static IEnumerable<TResu ...
- Linq中join & group join & left join 的用法
Linq中join & group join & left join 的用法 2013-01-30 11:12 12154人阅读 评论(0) 收藏 举报 分类: C#(14) 文章 ...
- LINQ查询操作符之Select、Where、OrderBy、OrderByDescending、GroupBy、Join、GroupJoin及其对应的查询语法
介绍 ·Select - Select选择:延迟 ·Where - Where查询:延迟 ·OrderBy - 按指定表达式对集合正序排序:延迟 ·OrderByDescend ...
- linq group join
本篇介绍Linq的Group和Join操作,继续使用<Linq 学习(3) 语法结构>中介绍的数据源. GroupGroup是进行分组操作,同SQL中的Group By类似.原型如下: p ...
- Lamda 表达式里的Join和GroupJoin的区别, 如何实现SQL的Left Join效果
例如,可以将产品表与产品类别表相联接,得到产品名称和与其相对应的类别名称 db.Products .Join ( db.Categories, p => p.CategoryID, c => ...
随机推荐
- Flask路由与蓝图Blueprint
需求分析: 当一个庞大的系统中有很多小模块,在分配路由的时候怎么处理呢?全部都堆到一个py程序中,调用@app.route? 显然这是很不明智的,因为当有几十个模块需要写路由的时候,这样程序员写着写着 ...
- thread/threading——Python多线程入门笔记
1 什么是线程? (1)线程不同于程序. 线程不能够独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制: 多线程类似于同时执行多个不同程序. (2)线程不同于进程. 每个独立的进程有一个程 ...
- Cygwin下编译的程序不使用Cygwin.dll即可运行的命令 及常用命令简介
cc -mno-cygwin foo.c 1.$ ps PS的相关用法: QuoteUsage ps [-aefl] [-u uid]-f = show process uids, ppids-l = ...
- ORACLE中内部函数SYS_OP_C2C和隐式类型转换
什么是SYS_OP_C2C呢?官方的介绍如下: SYS_OP_C2C is an internal function which does an implicit conversion of varc ...
- Eclipse启动时发生An internal error occurred duri ng: "Initializing Java Tooling ----网上的坑爹的一个方法
补充一下: 上面的方法不行. 我的个人解决方法 出现这种问题的原因,我的是eclipse换了,工作目录还是用之前的那个 把build Automatically的钩去掉 假设我们是用之前的worksp ...
- SQLServer基础之数据页类型:GAM,SGAM,PFS
简介 我们已经知道SQL Server IO最小的单位是页,连续的8个页是一个区.SQL Server需要一种方式来知道其所管辖的数据库中的空间使用情况,这就是GAM页和SGAM页. GAM页 GAM ...
- Windows Server 2016-配置Windows Defender防病毒排除项
Windows Server 2016 的计算机上的 Windows Defender 防病毒自动注册你在某些排除项,由你指定的服务器角色定义. 这些排除项不会显示在Windows 安全中心应用中所示 ...
- DNS区域传送漏洞实验以及二级域名爆破
DNS区域传送漏洞实验以及二级域名爆破 目录: 1.DNS服务器的域传送漏洞(nslookup交互式.非交互式.批处理三种方式) 2.写个二级域名爆破脚本 一.DNS服务器的域传送漏洞 实验环境: 服 ...
- 数组实例的 copyWithin()
用途:在当前数组内部,将指定位置的成员复制到其他位置(会覆盖原有成员),然后返回当前数组.也就是说,使用这个方法,会修改数组本身. 用法:Array.prototype.copyWithin(targ ...
- 设置Firefox自动清除缓存,无需手动清除
1.在firefox的地址栏上输入about:config回车 2.找到browser.cache.check_doc_frequency选项,双击将3改成1保存即可. 那么这个选项每个值都是什么含义 ...