IEnumerable的一些基本方法 补充
接上一篇,我们发现两表连接方式默认为内连接,而我们在SQL中常用到的左连接没有封装方法。换句话说,微软放弃两表左连或右连的这种做法(只有在2个表都存在值时,这样的连接才有意义)。
如果要实现表的左连接,就不能调用他现有的封装方法了,可以用LINQ来实现。
var joinTable = (from left in table1.AsEnumerable()
join right in table2.AsEnumerable()
on left["ID"].ToString() equals right["ID"].ToString() into newTable
from right in newTable.DefaultIfEmpty()
select new
{
LeftID = left["ID"].ToString(),
RightID = right != null ? right["ID"].ToString() : default(string),
LeftName = left["Name"].ToString(),
RightName = right != null ? right["Name"].ToString() : default(string)
}).ToList();
joinTable.ForEach(t => Console.WriteLine("{0}\t{1}\t{2}\t{3}", t.LeftID, t.RightID, t.LeftName, t.RightName));
功能是实现了,但是这样又要憋死一群强迫症患者,非要用Join封装方法来实现这个功能。
那我们就来手动封装一个左连接方法吧。
public static IEnumerable<Result> LeftJoin<TOuter, TInner, TKey, Result>(
this IEnumerable<TOuter> outer
, IEnumerable<TInner> inner
, Func<TOuter, TKey> outerKeySelector
, Func<TInner, TKey> innerKeySelector
, Func<TOuter, TInner, Result> resultSelector
, IEqualityComparer<TKey> comparer)
{
if (outer == null)
throw new ArgumentException("outer"); if (inner == null)
throw new ArgumentException("inner"); if (outerKeySelector == null)
throw new ArgumentException("outerKeySelector"); if (innerKeySelector == null)
throw new ArgumentException("innerKeySelector"); if (resultSelector == null)
throw new ArgumentException("resultSelector"); return LeftJoinImpl(outer, inner, outerKeySelector, innerKeySelector, resultSelector, comparer ?? EqualityComparer<TKey>.Default);
} static IEnumerable<Result> LeftJoinImpl<TOuter, TInner, TKey, Result>(
IEnumerable<TOuter> outer, IEnumerable<TInner> inner
, Func<TOuter, TKey> outerKeySelector
, Func<TInner, TKey> innerKeySelector
, Func<TOuter, TInner, Result> resultSelector
, IEqualityComparer<TKey> comparer)
{
var innerLookup = inner.ToLookup(innerKeySelector, comparer); foreach (var outerElment in outer)
{
var outerKey = outerKeySelector(outerElment);
var innerElements = innerLookup[outerKey]; if (innerElements.Any())
foreach (var innerElement in innerElements)
yield return resultSelector(outerElment, innerElement);
else
yield return resultSelector(outerElment, default(TInner));
}
}
PS:以上这段代码转载自stackoverflow.com
var joinTable = table1.AsEnumerable().LeftJoin(table2.AsEnumerable(),
left => left["ID"].ToString(),
right => right["ID"].ToString(),
(left, right) => new
{
LeftID = left["ID"].ToString(),
RightID = right != null ? right["ID"].ToString() : default(string),
LeftName = left["Name"].ToString(),
RightName = right != null ? right["Name"].ToString() : default(string)
}, null).ToList();
joinTable.ForEach(t => Console.WriteLine("{0}\t{1}\t{2}\t{3}", t.LeftID, t.RightID, t.LeftName, t.RightName));
是不是和之前的Join方法一样,这样用起来很方便了吧。
IEnumerable的一些基本方法 补充的更多相关文章
- C# 索引器,实现IEnumerable接口的GetEnumerator()方法
当自定义类需要实现索引时,可以在类中实现索引器. 用Table作为例子,Table由多个Row组成,Row由多个Cell组成, 我们需要实现自定义的table[0],row[0] 索引器定义格式为 [ ...
- 为IEnumerable扩展一个ForEach方法
IEnumerable没有一个ForEach方法,我们可以使用C#写一个扩展方法: Source Code: using System; using System.Collections.Generi ...
- IEnumerable接口的扩展方法
/// <summary>/// IEnumerable接口的扩展方法,支持它的实现类是List的情况/// </summary>using System.Collection ...
- python 魔法方法补充(__setattr__,__getattr__,__getattribute__)
python 魔法方法补充 1 getattribute (print(ob.name) -- obj.func())当访问对象的属性或者是方法的时候触发 class F(object): def _ ...
- python基础知识五 各类型数据方法补充,转换,分类,编码+坑中菜
3.9各类型数据方法补充,转换,分类,编码,坑中菜 3.9.1数据类型方法补充 1.str:不可变 补充方法 s1.capitalize():首字母大写 s1 = "alex" s ...
- C#对IQueryable<T>、IEnumerable<T>的扩展方法
#region IQueryable<T>的扩展方法 #region 根据第三方条件是否为真是否执行指定条件的查询 /// <summary> /// 根据第三方条件是否为真是 ...
- 像画笔一样慢慢画出Path的三种方法(补充第四种)
今天大家在群里大家非常热闹的讨论像画笔一样慢慢画出Path的这种效果该如何实现. 北京-LGL 博客号@ligl007发起了这个话题.然后各路高手踊跃发表意见.最后雷叔 上海-雷蒙 博客号@雷蒙之星 ...
- IEnumerable接口的Aggregate方法
以前小猪为了累加一个集合中的类容通常会写出类似这样的C#代码: string result ="": foreach (var item in items) { result+=i ...
- IEnumerable中的 Any方法
IEnumerable类中的 Any方法,表示集合中有任何一元素满足条件,返回就true , 该方法有两个重载 1. 不带任何参数,表示集合中有元素 2. 参入一个 Func<TSource, ...
随机推荐
- Vue实现远程获取路由与页面刷新导致404错误的解决
一.背景 先简单介绍一下现在项目情况:前后端分离,后端服务是Java写的,前端是Vue+ElementUI. 最近的一个需求是:通过后端Api去获取前端路由表,原因是每个登录角色对应的前端路由表可能是 ...
- encodeURI() 函数概述
encodeURI() 函数的作用是将URI中的某些特定的字符以一位到四位的转义序列来替代,这些转义序列就是这些字符的UTF-8编码(如果说某些字符是由两个代替字符构成的,该字符也只会是四位的转义序列 ...
- jqGrid单元格编辑配置,事件及方法
转自 http://blog.csdn.net/xueshijun666/article/details/18151055 // var ret = $("#in_store_list_de ...
- CodeForces 213 E
/* 线段树 + hash: 首先我们可以知道A序列是1~n的排列,那么我们可以先在B序列中把1~n的排列找出来,看其相对位置是否与A相同(hash可做),相同即表明存在一个d满足条件. 以此类推,我 ...
- hdu 5471(状压DP or 容斥)
想了最复杂的思路,用了最纠结的方法,花了最长的时间,蒙了一种规律然后莫名其妙的过了. MD 我也太淼了. 后面想了下用状压好像还是挺好写的,而且复杂度也不高.推出的这个容斥的规律也没完全想透我就CAO ...
- mysql 日期加减天数
MySQL 为日期增加一个时间间隔:date_add() now() //now函数为获取当前时间 select date_add(now(), interval 1 day); - 加1 ...
- 巨蟒python全栈开发flask目录
预习1: 1.FlaskWeb框架: https://www.cnblogs.com/DragonFire/category/1246076.html 人工智能技术应用: https://www.cn ...
- ORACLE日期时间函数
ORACLE日期时间函数大全 TO_DATE格式(以时间:2007-11-02 13:45:25为例) Year: yy two digits 两位年 ...
- js内置数据类型
JS 中分为七种内置类型,七种内置类型又分为两大类型:基本类型和对象(Object). 基本类型有六种: number , string , boolean , null , undefined , ...
- MySQL复制(一):复制的基本步骤
从这里开始,对复制的内容开始做一些详细的描述,复制从简单到入门 复制最简单的模式如下 基本的三个简单步骤 1 配置一个服务器为master 2 配置一个服务器为slave 3 将slave连接到mas ...