Linq 集合操作

演示代码

两个对象一个是Person,一个Address, AddressId是外键,

  1. public class Person
  2.  
  3. {
  4.  
  5. public string ID { get; set; }
  6.  
  7. public string Name { get; set; }
  8.  
  9. public int Age { get; set; }
  10.  
  11. public double Salary { get; set; }
  12.  
  13. public DateTime Born { get; set; }
  14.  
  15. public int IdAddress { get; set; }
  16.  
  17. }
  18.  
  19. public class Address
  20.  
  21. {
  22.  
  23. public int IdAddress { get; set; }
  24.  
  25. public string Street { get; set; }
  26.  
  27. public int Num { get; set; }
  28.  
  29. public string City { get; set; }
  30.  
  31. }

  

测试数据如下

Person类

Address类

下面我会用7个方式实现7中集合操作

  1. INNER JOIN 内链接
  2. LEFT JOIN 左连接
  3. RIGHT JOIN 右链接
  4. FULL OUTER JOIN 所有
  5. LEFT JOIN EXCLUDING INNER JOIN 左空
  6. RIGHT JOIN EXCLUDING INNER JOIN 右空
  7. FULL OUTER JOIN EXCLUDING INNER JOIN ??

    学校数学没学好不知道专业术语!哈哈

    INNER JOIN

    最常用的方法,两表关联查询

    标准Linq语法

    1. var result = from p in Person.BuiltPersons()
    2.  
    3. join a in Address.BuiltAddresses()
    4.  
    5. on p.IdAddress equals a.IdAddress
    6.  
    7. select new
    8.  
    9. {
    10.  
    11. Name = a.MyPerson.Name,
    12.  
    13. Age = a.MyPerson.Age,
    14.  
    15. PersonIdAddress = a.MyPerson.IdAddress,
    16.  
    17. AddressIdAddress = a.MyAddress.IdAddress,
    18.  
    19. Street = a.MyAddress.Street
    20.  
    21. };

      

    Lambda Expression:

    1. var resultJoint = Person.BuiltPersons().Join( /// Source Collection
    2.  
    3. Address.BuiltAddresses(), /// Inner Collection
    4.  
    5. p => p.IdAddress, /// PK
    6.  
    7. a => a.IdAddress, /// FK
    8.  
    9. (p, a) => new { MyPerson = p, MyAddress = a }) /// Result Collection
    10.  
    11. .Select(a => new
    12.  
    13. {
    14.  
    15. Name = a.MyPerson.Name,
    16.  
    17. Age = a.MyPerson.Age,
    18.  
    19. PersonIdAddress = a.MyPerson.IdAddress,
    20.  
    21. AddressIdAddress = a.MyAddress.IdAddress,
    22.  
    23. Street = a.MyAddress.Street
    24.  
    25. });

      

    Lambda表达式主要有5部分

  8. Is the main Collection. 
  9. Is the inner Collection.
  10. Is the PK.
  11. Is the FK.
  12. Is the type for the result collection. 

    查询结果如下

    LEFT JOIN

    新增一个LeftJoin的扩展方法

    1. public static IEnumerable<TResult>
    2.  
    3. LeftJoin<TSource, TInner, TKey, TResult>(this IEnumerable<TSource> source,
    4.  
    5. IEnumerable<TInner> inner,
    6.  
    7. Func<TSource, TKey> pk,
    8.  
    9. Func<TInner, TKey> fk,
    10.  
    11. Func<TSource, TInner, TResult> result)
    12.  
    13. {
    14.  
    15. IEnumerable<TResult> _result = Enumerable.Empty<TResult>();
    16.  
    17. _result = from s in source
    18.  
    19. join i in inner
    20.  
    21. on pk(s) equals fk(i) into joinData
    22.  
    23. from left in joinData.DefaultIfEmpty()
    24.  
    25. select result(s, left);
    26.  
    27. return _result;
    28.  
    29. }

      

    Lambda Expression:

    1. var resultJoint = Person.BuiltPersons().LeftJoin( /// Source Collection
    2.  
    3. Address.BuiltAddresses(), /// Inner Collection
    4.  
    5. p => p.IdAddress, /// PK
    6.  
    7. a => a.IdAddress, /// FK
    8.  
    9. (p, a) => new { MyPerson = p, MyAddress = a }) /// Result Collection
    10.  
    11. .Select(a => new
    12.  
    13. {
    14.  
    15. Name = a.MyPerson.Name,
    16.  
    17. Age = a.MyPerson.Age,
    18.  
    19. PersonIdAddress = a.MyPerson.IdAddress,
    20.  
    21. AddressIdAddress = (a.MyAddress != null ? a.MyAddress.IdAddress : -1),
    22.  
    23. Street = (a.MyAddress != null ? a.MyAddress.Street : "Null-Value")
    24.  
    25. });

      

    注意:如果address为空Null需要做一个替换,否则会报错

    查询结果如下

    RIGHT JOIN

    Extension Method:

    1. public static IEnumerable<TResult>
    2.  
    3. RightJoin<TSource, TInner, TKey, TResult>(this IEnumerable<TSource> source,
    4.  
    5. IEnumerable<TInner> inner,
    6.  
    7. Func<TSource, TKey> pk,
    8.  
    9. Func<TInner, TKey> fk,
    10.  
    11. Func<TSource, TInner, TResult> result)
    12.  
    13. {
    14.  
    15. IEnumerable<TResult> _result = Enumerable.Empty<TResult>();
    16.  
    17. _result = from i in inner
    18.  
    19. join s in source
    20.  
    21. on fk(i) equals pk(s) into joinData
    22.  
    23. from right in joinData.DefaultIfEmpty()
    24.  
    25. select result(right, i);
    26.  
    27. return _result;
    28.  
    29. }

      

    Lambda Expression:

    1. var resultJoint = Person.BuiltPersons().RightJoin( /// Source Collection
    2.  
    3. Address.BuiltAddresses(), /// Inner Collection
    4.  
    5. p => p.IdAddress, /// PK
    6.  
    7. a => a.IdAddress, /// FK
    8.  
    9. (p, a) => new { MyPerson = p, MyAddress = a }) /// Result Collection
    10.  
    11. .Select(a => new
    12.  
    13. {
    14.  
    15. Name = (a.MyPerson != null ? a.MyPerson.Name : "Null-Value"),
    16.  
    17. Age = (a.MyPerson != null ? a.MyPerson.Age : -1),
    18.  
    19. PersonIdAddress = (a.MyPerson != null ? a.MyPerson.IdAddress : -1),
    20.  
    21. AddressIdAddress = a.MyAddress.IdAddress,
    22.  
    23. Street = a.MyAddress.Street
    24.  
    25. });

      

    查询结果如下

    FULL OUTER JOIN

    Extension Method:

    1. public static IEnumerable<TResult>
    2.  
    3. FullOuterJoinJoin<TSource, TInner, TKey, TResult>(this IEnumerable<TSource> source,
    4.  
    5. IEnumerable<TInner> inner,
    6.  
    7. Func<TSource, TKey> pk,
    8.  
    9. Func<TInner, TKey> fk,
    10.  
    11. Func<TSource, TInner, TResult> result)
    12.  
    13. {
    14.  
    15. var left = source.LeftJoin(inner, pk, fk, result).ToList();
    16.  
    17. var right = source.RightJoin(inner, pk, fk, result).ToList();
    18.  
    19. return left.Union(right);
    20.  
    21. }

      

    Lambda Expression:

    1. var resultJoint = Person.BuiltPersons().FullOuterJoinJoin( /// Source Collection
    2.  
    3. Address.BuiltAddresses(), /// Inner Collection
    4.  
    5. p => p.IdAddress, /// PK
    6.  
    7. a => a.IdAddress, /// FK
    8.  
    9. (p, a) => new { MyPerson = p, MyAddress = a }) /// Result Collection
    10.  
    11. .Select(a => new
    12.  
    13. {
    14.  
    15. Name = (a.MyPerson != null ? a.MyPerson.Name : "Null-Value"),
    16.  
    17. Age = (a.MyPerson != null ? a.MyPerson.Age : -1),
    18.  
    19. PersonIdAddress = (a.MyPerson != null ? a.MyPerson.IdAddress : -1),
    20.  
    21. AddressIdAddress = (a.MyAddress != null ? a.MyAddress.IdAddress : -1),
    22.  
    23. Street = (a.MyAddress != null ? a.MyAddress.Street : "Null-Value")
    24.  
    25. });

      

    注意:每个对象都需要验证Null

    查询结果如下

    LEFT EXCLUDING JOIN

    Extension Method:

    1. public static IEnumerable<TResult>
    2.  
    3. LeftExcludingJoin<TSource, TInner, TKey, TResult>(this IEnumerable<TSource> source,
    4.  
    5. IEnumerable<TInner> inner,
    6.  
    7. Func<TSource, TKey> pk,
    8.  
    9. Func<TInner, TKey> fk,
    10.  
    11. Func<TSource, TInner, TResult> result)
    12.  
    13. {
    14.  
    15. IEnumerable<TResult> _result = Enumerable.Empty<TResult>();
    16.  
    17. _result = from s in source
    18.  
    19. join i in inner
    20.  
    21. on pk(s) equals fk(i) into joinData
    22.  
    23. from left in joinData.DefaultIfEmpty()
    24.  
    25. where left == null
    26.  
    27. select result(s, left);
    28.  
    29. return _result;
    30.  
    31. }

      

    Lambda Expression:

    1. var resultJoint = Person.BuiltPersons().LeftExcludingJoin( /// Source Collection
    2.  
    3. Address.BuiltAddresses(), /// Inner Collection
    4.  
    5. p => p.IdAddress, /// PK
    6.  
    7. a => a.IdAddress, /// FK
    8.  
    9. (p, a) => new { MyPerson = p, MyAddress = a }) /// Result Collection
    10.  
    11. .Select(a => new
    12.  
    13. {
    14.  
    15. Name = a.MyPerson.Name,
    16.  
    17. Age = a.MyPerson.Age,
    18.  
    19. PersonIdAddress = a.MyPerson.IdAddress,
    20.  
    21. AddressIdAddress = (a.MyAddress != null ? a.MyAddress.IdAddress : -1),
    22.  
    23. Street = (a.MyAddress != null ? a.MyAddress.Street : "Null-Value")
    24.  
    25. });

      

    查询结果如下

    RIGHT EXCLUDING JOIN

    Extension Method:

    1. public static IEnumerable<TResult>
    2.  
    3. RightExcludingJoin<TSource, TInner, TKey, TResult>(this IEnumerable<TSource> source,
    4.  
    5. IEnumerable<TInner> inner,
    6.  
    7. Func<TSource, TKey> pk,
    8.  
    9. Func<TInner, TKey> fk,
    10.  
    11. Func<TSource, TInner, TResult> result)
    12.  
    13. {
    14.  
    15. IEnumerable<TResult> _result = Enumerable.Empty<TResult>();
    16.  
    17. _result = from i in inner
    18.  
    19. join s in source
    20.  
    21. on fk(i) equals pk(s) into joinData
    22.  
    23. from right in joinData.DefaultIfEmpty()
    24.  
    25. where right == null
    26.  
    27. select result(right, i);
    28.  
    29. return _result;
    30.  
    31. }

      

    Lambda Expression:

    1. var resultJoint = Person.BuiltPersons().RightExcludingJoin( /// Source Collection
    2.  
    3. Address.BuiltAddresses(), /// Inner Collection
    4.  
    5. p => p.IdAddress, /// PK
    6.  
    7. a => a.IdAddress, /// FK
    8.  
    9. (p, a) => new { MyPerson = p, MyAddress = a }) /// Result Collection
    10.  
    11. .Select(a => new
    12.  
    13. {
    14.  
    15. Name = (a.MyPerson != null ? a.MyPerson.Name : "Null-Value"),
    16.  
    17. Age = (a.MyPerson != null ? a.MyPerson.Age : -1),
    18.  
    19. PersonIdAddress = (a.MyPerson != null ? a.MyPerson.IdAddress : -1),
    20.  
    21. AddressIdAddress = a.MyAddress.IdAddress,
    22.  
    23. Street = a.MyAddress.Street
    24.  
    25. });

      

    查询结果

    FULL OUTER EXCLUDING JOIN

    Extension Method:

    1. public static IEnumerable<TResult>
    2.  
    3. FulltExcludingJoin<TSource, TInner, TKey, TResult>(this IEnumerable<TSource> source,
    4.  
    5. IEnumerable<TInner> inner,
    6.  
    7. Func<TSource, TKey> pk,
    8.  
    9. Func<TInner, TKey> fk,
    10.  
    11. Func<TSource, TInner, TResult> result)
    12.  
    13. {
    14.  
    15. var left = source.LeftExcludingJoin(inner, pk, fk, result).ToList();
    16.  
    17. var right = source.RightExcludingJoin(inner, pk, fk, result).ToList();
    18.  
    19. return left.Union(right);
    20.  
    21. }

      

    Lambda Expression:

    1. var resultJoint = Person.BuiltPersons().FulltExcludingJoin( /// Source Collection
    2.  
    3. Address.BuiltAddresses(), /// Inner Collection
    4.  
    5. p => p.IdAddress, /// PK
    6.  
    7. a => a.IdAddress, /// FK
    8.  
    9. (p, a) => new { MyPerson = p, MyAddress = a }) /// Result Collection
    10.  
    11. .Select(a => new
    12.  
    13. {
    14.  
    15. Name = (a.MyPerson != null ? a.MyPerson.Name : "Null-Value"),
    16.  
    17. Age = (a.MyPerson != null ? a.MyPerson.Age : -1),
    18.  
    19. PersonIdAddress = (a.MyPerson != null ? a.MyPerson.IdAddress : -1),
    20.  
    21. AddressIdAddress = (a.MyAddress != null ? a.MyAddress.IdAddress : -1),
    22.  
    23. Street = (a.MyAddress != null ? a.MyAddress.Street : "Null-Value")
    24.  
    25. });

      

    查询结果

Linq 集合操作的更多相关文章

  1. Linq集合操作之Intersect,Except,Union源码分析

    Linq集合操作之Intersect,Except,Union源码分析 linq的集合运算 常见的集合运算有哪些? 这三个扩展方法在我们实际使用中用的还是非常多的,而且这里还涉及到了“复杂度” 无算法 ...

  2. C#LINQ集合操作

    LINQ的集合运算 List<int> lstOne = new List<int>() { 1, 55, 223, 25 }; List<int> lstTwo ...

  3. Linq聚合操作之Aggregate,Count,Sum,Distinct源码分析

    Linq聚合操作之Aggregate,Count,Sum,Distinct源码分析 一:Linq的聚合运算 1. 常见的聚合运算:Aggregate,Count, Sum, Distinct,Max, ...

  4. Linq生成操作之DefautIfEmpty,Empty,Range,Repeat源码分析

    Linq生成操作之DefautIfEmpty,Empty,Range,Repeat源码分析 Linq的四种生成运算 DefautIfEmpty,Empty,Range,Repeat 也就是给我们初始化 ...

  5. Linq转换操作之OfType,Cast,AsEnumerable,ToLookup源码分析

    Linq转换操作之OfType,Cast,AsEnumerable,ToLookup源码分析 一:Tolookup 1. 从方法的注解上可以看到,ToLookup也是一个k,v的形式,那么问题来了,它 ...

  6. Linq转换操作之ToArray,ToList,ToDictionary源码分析

    Linq转换操作之ToArray,ToList,ToDictionary源码分析 一:linq中的转换运算符 1. ToArray 我们经常用在linq查询上吧. linq只能运用在IEnumerab ...

  7. 函数式Android编程(II):Kotlin语言的集合操作

    原文标题:Functional Android (II): Collection operations in Kotlin 原文链接:http://antonioleiva.com/collectio ...

  8. JAVASE02-Unit05: 集合操作 —— 查找表

    Unit05: 集合操作 -- 查找表 使用该类测试自定义元素的集合排序 package day05; /** * 使用该类测试自定义元素的集合排序 * @author adminitartor * ...

  9. JAVASE02-Unit04: 集合框架 、 集合操作 —— 线性表

    Unit04: 集合框架 . 集合操作 -- 线性表 操作集合元素相关方法 package day04; import java.util.ArrayList; import java.util.Co ...

随机推荐

  1. (简单) HUST 1017 Exact cover , DLX+精确覆盖。

    Description There is an N*M matrix with only 0s and 1s, (1 <= N,M <= 1000). An exact cover is ...

  2. [Lua]Mac系统上安装Lua环境

    1.下载 Lua语言的官方网站 http://www.lua.org/ 下载最新版本的Lua环境 2.安装 解压下载包lua-5.3.1.tar.gz 打开终端Terminal 使用cd命令进入该目录 ...

  3. ListView与RadioButton组合——自定义单选列表

      标签: radiobuttonlistviewandroidlayout 2013-09-10 11:13 19396人阅读 评论(8) 收藏 举报  分类: Android(19)  版权声明: ...

  4. java8 泛型声明 The diamond operator ("<>") should be used

    The diamond operator ("<>") should be used Java 7 introduced the diamond operator (& ...

  5. 递归添加 另一个ds 里的DataRow 时 报错:该行已经属于另一个表。

    public void create_tree(DataSet ds, int parentid)        { DataSet newds = new DataSet();            ...

  6. UVa 507 - Jill Rides Again

    题目大意:最大和子序列问题.由于具有最大和的子序列具有一下性质:第一项不为负数,并且从第一项开始累加,中间不会有和出现负数,因为一旦有负数我们可以抛弃前边的部分以得到更大的子序列和,这将会产生矛盾. ...

  7. 扫码JSP

    扫码 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.o ...

  8. Mac下使用Brew搭建PHP(LNMP/LAMP)开发环境

    Mac下搭建lamp开发环境很容易,有xampp和mamp现成的集成环境.但是集成环境对于经常需要自定义一些配置的开发者来说会非常麻烦,而且Mac本身自带apache和php,在brew的帮助下非常容 ...

  9. JavaScript 扯几句单线程相关

    JavaScript 扯几句单线程相关 众所周知,Javascript是单线程执行的,这也就是说:JavaScript在同一个时间上只能处理一件事.他不像C,Java等这些多 线程的,可以开不同的线程 ...

  10. Visual Studio 2015的安装与基本使用

    为什么要使用Visual Studio 2015? 它是中文的.界面友好.自动补全.实时语法错误提示(上图中波浪线部分).单步调试……最重要的社区版是免费的!所以你不必再使用破解的.老旧的的不兼容现代 ...