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, ...
随机推荐
- 【问题】CentOS6.5系统"libc.so.6: version 'GLIBC_2.15' not found"解决方法
出现"libc.so.6: version 'GLIBC_2.15' not found"问题,是由于glibc版本过低,升级glibc即可. 由于CentOS系统RPM源目前gl ...
- Laravel开发:Laravel核心——Ioc服务容器源码解析(服务器解析)
make解析 服务容器对对象的自动解析是服务容器的核心功能,make 函数.build 函数是实例化对象重要的核心,先大致看一下代码: public function make($abstract) ...
- urllib -- ProxyHandler处理器(代理设置)
import urllib.requestimport randomimport ssl proxy_list = [ {"https" : "196.61.27.58: ...
- OKhttp3
针对上一博文订单调用用户使用默认数据交互方式,下面介绍下使用 Okhttp3网络数据交换方式. 1.订单启动类变化 package com.tycoon.orderService; import or ...
- NET Framework 4.5新特性 (一) 数据库的连接加密保护。
NET Framework 4.5 ado.net数据库连接支持使用SecureString内存流方式保密文本. 一旦使用这类操作,文本加密是私有不能共享的,并在不再需要时从计算机内存中删除. S ...
- 1677 treecnt(贡献)
1677 treecnt 基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题 给定一棵n个节点的树,从1到n标号.选择k个点,你需要选择一些边使得这k个点通过选择的边联 ...
- JS实现全选,全不选
<script type="text/javascript"> function selectItem() { document.getElementById(&quo ...
- JQuery处理DOM元素
现有一个id为txtMyTest的元素 获取属性值 $('#id').attr('属性名'); 设置属性值 $('#id').attr('属性名','需要设置的值'); 设置多个属性 如下同时设置va ...
- CAS单点登录------302个没完没了
我的配置如上 背景:Shiro + Cas 进行的单点登录配置! 其实这个问题很扯淡!看代码! 我本在shiro里面配置的Sucessurl !嘿嘿!我哭了!屌用没有! 我一脸懵逼大写的WHY??? ...
- 谷歌浏览器input中的text 和 button 水平对齐的问题
方法一 text 的vertical-align :top; 方法二 button的vertical-align: middle;