欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

[C#] LINQ之Join与GroupJoin

程序员文章站 2022-05-08 08:13:32
声明:本文为www.cnc6.cn原创,转载时请注明出处,谢谢! 一、编写Person与City类,如下: 二、为以上两个类建立一些数据,存储于persons与cities中,如下: 三、Join第一种用法: 官方释义:基于匹配键对两个序列的元素进行关联。使用默认的相等比较器对键进行比较。 这个与数 ......

声明:本文为原创,转载时请注明出处,谢谢!

一、编写person与city类,如下:

 1     class person
 2     {
 3         public int cityid { set; get; }
 4         public string name { set; get; }
 5     }
 6     class city
 7     {
 8         public int id { set; get; }
 9         public string name { set; get; }
10     }

二、为以上两个类建立一些数据,存储于persons与cities中,如下:

 1     person[] persons = new person[]
 2     {
 3         new person{ cityid = 1, name = "abc" },
 4         new person{ cityid = 1, name = "efg" },
 5         new person{ cityid = 2, name = "hij" },
 6         new person{ cityid = 3, name = "klm" },
 7         new person{ cityid = 3, name = "nop" },
 8         new person{ cityid = 4, name = "qrs" },
 9         new person{ cityid = 5, name = "tuv" }
10     };
11     city[] cities = new city[]
12     {
13         new city{ id = 1,name = "guangzhou" },
14         new city{ id = 2,name = "shenzhen" },
15         new city{ id = 3,name = "beijing" },
16         new city{ id = 4,name = "shanghai" }
17     };

三、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、返回的结果就是自己定义类型的集合。

编写客户端试验代码:

1     var result =  persons.join(cities, p => p.cityid, c => c.id, (p, c) => new { personname = p.name, cityname = c.name});
2     foreach(var item in result)
3     {
4         console.writeline($"{item.personname},{item.cityname}");
5     }

从以上可以看出,persons为outer集合,cities为inner集合,p.cityid为outer的键值,c.id为inner的键值,join就是将persons内cityid与cities内id相等性连接起来,并将persons内的每个元素及cities内的每个元素作为输入参数,从从选择自己想要的数据,如自己定义的匿名类型。

因为persons内cityid为5的城市编号不存在与cities内,因此输出结果不会含name为“tuv”的信息。

输出结果如下:

[C#] LINQ之Join与GroupJoin

其等价的linq语句为:

1     var result = from p in persons
2                  join c in cities on p.cityid equals c.id
3                  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的连接。

编写客户端试验代码:

 1     var result = persons.groupjoin(cities, p => p.cityid, c => c.id, (p, cs) => new { personname = p.name, citys = cs });
 2     foreach (var item in result)
 3     {
 4         console.write($"{item.personname}\t");
 5         foreach (var city in item.citys)
 6         {
 7             console.write($"{city.name}");
 8         }
 9         console.writeline();
10     }

这个输出会将name为“tuv”的名字输出,但其城市却是空的,原因就是在cities找不到编号为5的city信息。

输出结果如下:

[C#] LINQ之Join与GroupJoin

其等价的linq语句为:

1     var result = from p in persons
2                  join c in cities on p.cityid equals c.id into cs
3                  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第二种方法类似,这里不再进行讲述。