在LINQ中,join可以实现3种类型的联接,分别是内部联接、分组联接、左外部联接。
- 内部联接:
private static void UseInnnerJoin() { int[] intArray1 = { 5, 15, 25, 30, 33, 40 }; int[] intArray2 = { 10, 20, 30, 50, 60, 70, 80 }; var query1 = from val1 in intArray1 join val2 in intArray2 on val1 % 5 equals val2 % 15 select new { VAL1 = val1, VAL2 = val2 }; foreach (var item in query1) { Console.WriteLine(item); } }
运行结果:
{ VAL1 = 5, VAL2 = 30 } { VAL1 = 5, VAL2 = 60 } { VAL1 = 15, VAL2 = 30 } { VAL1 = 15, VAL2 = 60 } { VAL1 = 25, VAL2 = 30 } { VAL1 = 25, VAL2 = 60 } { VAL1 = 30, VAL2 = 30 } { VAL1 = 30, VAL2 = 60 } { VAL1 = 40, VAL2 = 30 } { VAL1 = 40, VAL2 = 60 }
- 分组联接:可用于产生分层的数据结果,它将第一个集合中的每个元素与第二个集合中的一组相关元素进行分配。即使第一个集合中的元素在第二个集合中没有配对元素,也会为它产生一个空的分组对象。
private static void UseGroupJoin() { int[] intArray1 = {5, 15, 25, 30, 33, 40}; int[] intArray2 = {10, 20, 30, 50, 60, 70, 80}; var query1 = from val1 in intArray1 join val2 in intArray2 on val1 % 5 equals val2 % 15 into val2Group select new {VAL1 = val1, VAL2Group = val2Group }; foreach (var item in query1) { Console.WriteLine(item.VAL1); foreach (var subItem in item.VAL2Group) { Console.WriteLine(subItem); } Console.WriteLine(); } }
- 左外部联接:返回第一个集合中的所有元素,无论它是否在第二个集合中有相关元素。在LINQ中,通过对分组链接的结果调用DefaultIfEmpty()方法来执行左外部联接。DefaultIfEmpty()从列表中获取指定元素,如果列表为空,则返回默认值。
private static void UseLeftJoin() { int[] intArray1 = { 5, 15, 25, 30, 33, 40 }; int[] intArray2 = { 10, 20, 30, 50, 60, 70, 80 }; var query1 = from val1 in intArray1 join val2 in intArray2 on val1 % 5 equals val2 % 15 into val2Group from grp in val2Group.DefaultIfEmpty() select new { VAL1 = val1, VAL2Group = grp }; foreach (var item in query1) { Console.WriteLine(item); } }
运行结果:
{ VAL1 = 5, VAL2Group = 30 } { VAL1 = 5, VAL2Group = 60 } { VAL1 = 15, VAL2Group = 30 } { VAL1 = 15, VAL2Group = 60 } { VAL1 = 25, VAL2Group = 30 } { VAL1 = 25, VAL2Group = 60 } { VAL1 = 30, VAL2Group = 30 } { VAL1 = 30, VAL2Group = 60 } { VAL1 = 33, VAL2Group = 0 } { VAL1 = 40, VAL2Group = 30 } { VAL1 = 40, VAL2Group = 60 }
左外部联接和分组联接虽然相似但并非一样。分组联接返回的查询结果是一种分层数据结构,需要使用两层foreach才能遍历它的结果。而左外部联接是在分组联接的查询结果上再进行一次查询,所以它在join之后还有一个from子句进行查询。