Linq 集合操作
Linq 集合操作
演示代码
两个对象一个是Person,一个Address, AddressId是外键,
public class Person
{
public string ID { get; set; }
public string Name { get; set; }
public int Age { get; set; }
public double Salary { get; set; }
public DateTime Born { get; set; }
public int IdAddress { get; set; }
}
public class Address
{
public int IdAddress { get; set; }
public string Street { get; set; }
public int Num { get; set; }
public string City { get; set; }
}
测试数据如下
Person类

Address类

下面我会用7个方式实现7中集合操作
- INNER JOIN 内链接
- LEFT JOIN 左连接
- RIGHT JOIN 右链接
- FULL OUTER JOIN 所有
- LEFT JOIN EXCLUDING INNER JOIN 左空
- RIGHT JOIN EXCLUDING INNER JOIN 右空
- FULL OUTER JOIN EXCLUDING INNER JOIN ??
学校数学没学好不知道专业术语!哈哈
INNER JOIN
最常用的方法,两表关联查询

标准Linq语法
var result = from p in Person.BuiltPersons() join a in Address.BuiltAddresses() on p.IdAddress equals a.IdAddress select new { Name = a.MyPerson.Name, Age = a.MyPerson.Age, PersonIdAddress = a.MyPerson.IdAddress, AddressIdAddress = a.MyAddress.IdAddress, Street = a.MyAddress.Street };Lambda Expression:
var resultJoint = Person.BuiltPersons().Join( /// Source Collection Address.BuiltAddresses(), /// Inner Collection p => p.IdAddress, /// PK a => a.IdAddress, /// FK (p, a) => new { MyPerson = p, MyAddress = a }) /// Result Collection .Select(a => new { Name = a.MyPerson.Name, Age = a.MyPerson.Age, PersonIdAddress = a.MyPerson.IdAddress, AddressIdAddress = a.MyAddress.IdAddress, Street = a.MyAddress.Street });Lambda表达式主要有5部分
- Is the main Collection.
- Is the inner Collection.
- Is the PK.
- Is the FK.
- Is the type for the result collection.
查询结果如下

LEFT JOIN

新增一个LeftJoin的扩展方法
public static IEnumerable<TResult> LeftJoin<TSource, TInner, TKey, TResult>(this IEnumerable<TSource> source, IEnumerable<TInner> inner, Func<TSource, TKey> pk, Func<TInner, TKey> fk, Func<TSource, TInner, TResult> result) { IEnumerable<TResult> _result = Enumerable.Empty<TResult>(); _result = from s in source join i in inner on pk(s) equals fk(i) into joinData from left in joinData.DefaultIfEmpty() select result(s, left); return _result; }Lambda Expression:
var resultJoint = Person.BuiltPersons().LeftJoin( /// Source Collection Address.BuiltAddresses(), /// Inner Collection p => p.IdAddress, /// PK a => a.IdAddress, /// FK (p, a) => new { MyPerson = p, MyAddress = a }) /// Result Collection .Select(a => new { Name = a.MyPerson.Name, Age = a.MyPerson.Age, PersonIdAddress = a.MyPerson.IdAddress, AddressIdAddress = (a.MyAddress != null ? a.MyAddress.IdAddress : -1), Street = (a.MyAddress != null ? a.MyAddress.Street : "Null-Value") });注意:如果address为空Null需要做一个替换,否则会报错
查询结果如下

RIGHT JOIN

Extension Method:
public static IEnumerable<TResult> RightJoin<TSource, TInner, TKey, TResult>(this IEnumerable<TSource> source, IEnumerable<TInner> inner, Func<TSource, TKey> pk, Func<TInner, TKey> fk, Func<TSource, TInner, TResult> result) { IEnumerable<TResult> _result = Enumerable.Empty<TResult>(); _result = from i in inner join s in source on fk(i) equals pk(s) into joinData from right in joinData.DefaultIfEmpty() select result(right, i); return _result; }Lambda Expression:
var resultJoint = Person.BuiltPersons().RightJoin( /// Source Collection Address.BuiltAddresses(), /// Inner Collection p => p.IdAddress, /// PK a => a.IdAddress, /// FK (p, a) => new { MyPerson = p, MyAddress = a }) /// Result Collection .Select(a => new { Name = (a.MyPerson != null ? a.MyPerson.Name : "Null-Value"), Age = (a.MyPerson != null ? a.MyPerson.Age : -1), PersonIdAddress = (a.MyPerson != null ? a.MyPerson.IdAddress : -1), AddressIdAddress = a.MyAddress.IdAddress, Street = a.MyAddress.Street });查询结果如下

FULL OUTER JOIN

Extension Method:
public static IEnumerable<TResult> FullOuterJoinJoin<TSource, TInner, TKey, TResult>(this IEnumerable<TSource> source, IEnumerable<TInner> inner, Func<TSource, TKey> pk, Func<TInner, TKey> fk, Func<TSource, TInner, TResult> result) { var left = source.LeftJoin(inner, pk, fk, result).ToList(); var right = source.RightJoin(inner, pk, fk, result).ToList(); return left.Union(right); }Lambda Expression:
var resultJoint = Person.BuiltPersons().FullOuterJoinJoin( /// Source Collection Address.BuiltAddresses(), /// Inner Collection p => p.IdAddress, /// PK a => a.IdAddress, /// FK (p, a) => new { MyPerson = p, MyAddress = a }) /// Result Collection .Select(a => new { Name = (a.MyPerson != null ? a.MyPerson.Name : "Null-Value"), Age = (a.MyPerson != null ? a.MyPerson.Age : -1), PersonIdAddress = (a.MyPerson != null ? a.MyPerson.IdAddress : -1), AddressIdAddress = (a.MyAddress != null ? a.MyAddress.IdAddress : -1), Street = (a.MyAddress != null ? a.MyAddress.Street : "Null-Value") });注意:每个对象都需要验证Null
查询结果如下

LEFT EXCLUDING JOIN

Extension Method:
public static IEnumerable<TResult> LeftExcludingJoin<TSource, TInner, TKey, TResult>(this IEnumerable<TSource> source, IEnumerable<TInner> inner, Func<TSource, TKey> pk, Func<TInner, TKey> fk, Func<TSource, TInner, TResult> result) { IEnumerable<TResult> _result = Enumerable.Empty<TResult>(); _result = from s in source join i in inner on pk(s) equals fk(i) into joinData from left in joinData.DefaultIfEmpty() where left == null select result(s, left); return _result; }Lambda Expression:
var resultJoint = Person.BuiltPersons().LeftExcludingJoin( /// Source Collection Address.BuiltAddresses(), /// Inner Collection p => p.IdAddress, /// PK a => a.IdAddress, /// FK (p, a) => new { MyPerson = p, MyAddress = a }) /// Result Collection .Select(a => new { Name = a.MyPerson.Name, Age = a.MyPerson.Age, PersonIdAddress = a.MyPerson.IdAddress, AddressIdAddress = (a.MyAddress != null ? a.MyAddress.IdAddress : -1), Street = (a.MyAddress != null ? a.MyAddress.Street : "Null-Value") });查询结果如下

RIGHT EXCLUDING JOIN

Extension Method:
public static IEnumerable<TResult> RightExcludingJoin<TSource, TInner, TKey, TResult>(this IEnumerable<TSource> source, IEnumerable<TInner> inner, Func<TSource, TKey> pk, Func<TInner, TKey> fk, Func<TSource, TInner, TResult> result) { IEnumerable<TResult> _result = Enumerable.Empty<TResult>(); _result = from i in inner join s in source on fk(i) equals pk(s) into joinData from right in joinData.DefaultIfEmpty() where right == null select result(right, i); return _result; }Lambda Expression:
var resultJoint = Person.BuiltPersons().RightExcludingJoin( /// Source Collection Address.BuiltAddresses(), /// Inner Collection p => p.IdAddress, /// PK a => a.IdAddress, /// FK (p, a) => new { MyPerson = p, MyAddress = a }) /// Result Collection .Select(a => new { Name = (a.MyPerson != null ? a.MyPerson.Name : "Null-Value"), Age = (a.MyPerson != null ? a.MyPerson.Age : -1), PersonIdAddress = (a.MyPerson != null ? a.MyPerson.IdAddress : -1), AddressIdAddress = a.MyAddress.IdAddress, Street = a.MyAddress.Street });查询结果

FULL OUTER EXCLUDING JOIN

Extension Method:
public static IEnumerable<TResult> FulltExcludingJoin<TSource, TInner, TKey, TResult>(this IEnumerable<TSource> source, IEnumerable<TInner> inner, Func<TSource, TKey> pk, Func<TInner, TKey> fk, Func<TSource, TInner, TResult> result) { var left = source.LeftExcludingJoin(inner, pk, fk, result).ToList(); var right = source.RightExcludingJoin(inner, pk, fk, result).ToList(); return left.Union(right); }Lambda Expression:
var resultJoint = Person.BuiltPersons().FulltExcludingJoin( /// Source Collection Address.BuiltAddresses(), /// Inner Collection p => p.IdAddress, /// PK a => a.IdAddress, /// FK (p, a) => new { MyPerson = p, MyAddress = a }) /// Result Collection .Select(a => new { Name = (a.MyPerson != null ? a.MyPerson.Name : "Null-Value"), Age = (a.MyPerson != null ? a.MyPerson.Age : -1), PersonIdAddress = (a.MyPerson != null ? a.MyPerson.IdAddress : -1), AddressIdAddress = (a.MyAddress != null ? a.MyAddress.IdAddress : -1), Street = (a.MyAddress != null ? a.MyAddress.Street : "Null-Value") });查询结果

Linq 集合操作的更多相关文章
- Linq集合操作之Intersect,Except,Union源码分析
Linq集合操作之Intersect,Except,Union源码分析 linq的集合运算 常见的集合运算有哪些? 这三个扩展方法在我们实际使用中用的还是非常多的,而且这里还涉及到了“复杂度” 无算法 ...
- C#LINQ集合操作
LINQ的集合运算 List<int> lstOne = new List<int>() { 1, 55, 223, 25 }; List<int> lstTwo ...
- Linq聚合操作之Aggregate,Count,Sum,Distinct源码分析
Linq聚合操作之Aggregate,Count,Sum,Distinct源码分析 一:Linq的聚合运算 1. 常见的聚合运算:Aggregate,Count, Sum, Distinct,Max, ...
- Linq生成操作之DefautIfEmpty,Empty,Range,Repeat源码分析
Linq生成操作之DefautIfEmpty,Empty,Range,Repeat源码分析 Linq的四种生成运算 DefautIfEmpty,Empty,Range,Repeat 也就是给我们初始化 ...
- Linq转换操作之OfType,Cast,AsEnumerable,ToLookup源码分析
Linq转换操作之OfType,Cast,AsEnumerable,ToLookup源码分析 一:Tolookup 1. 从方法的注解上可以看到,ToLookup也是一个k,v的形式,那么问题来了,它 ...
- Linq转换操作之ToArray,ToList,ToDictionary源码分析
Linq转换操作之ToArray,ToList,ToDictionary源码分析 一:linq中的转换运算符 1. ToArray 我们经常用在linq查询上吧. linq只能运用在IEnumerab ...
- 函数式Android编程(II):Kotlin语言的集合操作
原文标题:Functional Android (II): Collection operations in Kotlin 原文链接:http://antonioleiva.com/collectio ...
- JAVASE02-Unit05: 集合操作 —— 查找表
Unit05: 集合操作 -- 查找表 使用该类测试自定义元素的集合排序 package day05; /** * 使用该类测试自定义元素的集合排序 * @author adminitartor * ...
- JAVASE02-Unit04: 集合框架 、 集合操作 —— 线性表
Unit04: 集合框架 . 集合操作 -- 线性表 操作集合元素相关方法 package day04; import java.util.ArrayList; import java.util.Co ...
随机推荐
- [iOS]C语言知识点系列视频
C语言知识点系列视频 目录 C语言技术视频-01-变量的定义 C语言技术视频-02-程序分支结构(if...else) C语言技术视频-03-程序分支结构(switch) C语言技术视频-04-程序循 ...
- java类集: collection, list , set, map
都在java.util包里.容器:装各种对象. Collections类 : 集合工具类, 提供了一些静态方法, 方法里的参数是List等. Colection接口,子接口主要有: Set: 内容 ...
- android Makefile把jar包打到apk里
这个是经常的需求,我就是经常忘,关键不理解啊. 反反复复的也看看了android makefile. 太复杂了. 慢慢来吧.哎.工作十年.啥也不会.咋整? ## Copyright (C) 2008 ...
- UIResponder学习
http://blog.csdn.net/jimzhai/article/details/23283515 UIResponder 介绍 UIResponder 这个类定义了很多用来处理响应和时间处理 ...
- Mapreduce TopK
思想比较简单,就是每个通过map来获取当前的数据块中的的topk个数据,然后将他们以相同的key值放到reduce中,最后通过reduce来对这n*k个数据排序并获得topk个数据.具体的就是建立 ...
- Zynq和microblaze的区别
Zynq钩中PS端的外设之后不需要初始化过程,但是如果在microblaze中连接外设之后需要有初始化过程.
- 每个Javascript开发者都应当知道的那些事
每个Javascript开发者都应当知道的那些事 2015-06-07 前端大全 (点击上方蓝字,可快速关注我们) Javascript是一种日益增长的语言,特别是现在ECMAScript规范按照每年 ...
- JQuery的 jQuery.fn.extend() 和jQuery.extend();
原文链接:http://caibaojian.com/jquery-extend-and-jquery-fn-extend.html jQuery.fn.extend(); jQuery.extend ...
- Myeclipseforspring 10破解
破解包和说明下载网址:http://ishare.iask.sina.com.cn/f/33848276.html?all=y
- MMA
在32位的系统上,线性地址空间可达到4GB,这4GB一般按照3:1的比例进行分配,也就是说用户进程享有前3GB线性地址空间,而内核独享最后1GB线性地址空间.由于虚拟内存的引入,每个进程都可拥有3GB ...