猿教程 Logo

Linq连接运算符:GroupJoin

我们已经在上一节中看到了Join运算符。 GroupJoin运算符执行与Join运算符相同的任务,但GroupJoin根据指定的key组返回组中的结果。 GroupJoin运算符基于键连接两个序列,并通过匹配键对结果进行分组,然后返回分组结果和键的集合。


方法语法中的GroupJoin:

GroupJoin需要与Join相同的参数。 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);

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);

如你所见,第一个重载方法需要五个输入参数(除了第一个'this'参数):1)outer 2)inner 3)outerKeySelector 4)innerKeySelector 5)resultSelector。 请注意,resultSelector是Func委托类型,具有第二个输入参数作为内部序列的IEnumerable类型。

现在,让我们使用以下Student和Standard类来了解GroupJoin,其中Student类包括与Standard类的StandardID匹配的StandardID。

相关实例:

public class Student{ 
    public int StudentID { get; set; }
    public string StudentName { get; set; }
    public int StandardID { get; set; }
}

public class Standard{ 
    public int StandardID { get; set; }
    public string StandardName { get; set; }
}

参考下面的GroupJoin查询示例。

相关实例:

IList<Student> studentList = new List<Student>() { 
    new Student() { StudentID = 1, StudentName = "John", StandardID =1 },
    new Student() { StudentID = 2, StudentName = "Moin", StandardID =1 },
    new Student() { StudentID = 3, StudentName = "Bill", StandardID =2 },
    new Student() { StudentID = 4, StudentName = "Ram",  StandardID =2 },
    new Student() { StudentID = 5, StudentName = "Ron" } 
};

IList<Standard> standardList = new List<Standard>() { 
    new Standard(){ StandardID = 1, StandardName="Standard 1"},
    new Standard(){ StandardID = 2, StandardName="Standard 2"},
    new Standard(){ StandardID = 3, StandardName="Standard 3"}
};

var groupJoin = standardList.GroupJoin(studentList,  //inner sequence
                                std => std.StandardID, //outerKeySelector 
                                s => s.StandardID,     //innerKeySelector
                                (std, studentsGroup) => new // resultSelector 
                                {
                                    Students = studentsGroup,
                                    StandarFulldName = std.StandardName
                                });

foreach (var item in groupJoin)
{ 
    Console.WriteLine(item.StandarFulldName );

    foreach(var stud in item.Students)
        Console.WriteLine(stud.StudentName);
}

运行结果:

Standard 1: 
John, 
Moin, 
Standard 2: 
Bill, 
Ram, 
Standard 3:

在上面的GroupJoin查询示例中,standardList是外部序列,因为查询从它开始。 GroupJoin方法中的第一个参数是指定内部序列,在上面的示例中是studentList。 GroupJoin()方法的第二个和第三个参数是指定一个字段,其值应该使用lambda表达式来匹配,以便在结果中包含元素。 外部序列标准的键选择器=> standard.StandardID表示standardList中每个元素的StandardID字段应与内部序列studentList student => student.StandardID的键匹配。 如果两个键字段的值匹配,则将该元素包含到分组集合studentsGroup其中键将是StandardID。

Join方法中的最后一个参数是用于表达结果的表达式。 在上面的示例中,结果选择器包括分组集合studentGroup和StandardName。

以下图像说明分组为用于匹配StandardID键的students集合的内部序列和该分组集合可以用于公式化结果。


Resultset将包含具有Students和StandardFullName属性的匿名对象。 学生资源将是StandardID与Standard.StandardID匹配的学生的集合。


您可以使用“foreach”循环访问结果。 每个元素都将有标准全名和学生资源,学生将是一个集合。

相关实例:

foreach (var item in groupJoinResult)
{ 
    Console.WriteLine(item.StandarFulldName );

    foreach(var stud in item.Students)
        Console.WriteLine(stud.StudentName);
}

下面是VB.Net中GroupJoin的一个例子:

相关实例:

Dim groupJoin = standardList.GroupJoin(  ' outer sequence 
                    studentList, ' inner sequence 
                    Function(s) s.StandardID, ' outerKeySelector  
                    Function(stud) stud.StandardID, ' innerKeySelector 
                    Function(s, studentGroup) New With { ' result selector
                            .students = studentGroup, 
                            .standardName = s.StandardName
                    })

For Each item In groupJoin
    
    Console.WriteLine(item.standardName)
            
    For Each std In item.students
            Console.WriteLine( std.StudentName)
    Next

Next

运行结果:

Standard 1: 
John,
Moin,
Standard 2:
Bill,
Ram,
Standard 3:

查询语法中的GroupJoin:

查询语法中的GroupJoin运算符与方法语法略有不同。 它需要外部序列,内部序列,键选择器和结果选择器。 'on'关键字用于键选择器,其中'equals'运算符的左侧是outerKeySelector,'equals'的右侧是innerKeySelector。 使用into关键字创建分组的集合。

相关实例:

from ... in outerSequence 
        join ... in innerSequence  
        on outerKey equals innerKey 
            into groupedCollection    
        select ...

以下示例演示了GroupJoin的查询语法。

相关实例:

IList<Student> studentList = new List<Student>() { 
    new Student() { StudentID = 1, StudentName = "John", Age = 13, StandardID =1 },
    new Student() { StudentID = 2, StudentName = "Moin",  Age = 21, StandardID =1 },
    new Student() { StudentID = 3, StudentName = "Bill",  Age = 18, StandardID =2 },
    new Student() { StudentID = 4, StudentName = "Ram" , Age = 20, StandardID =2 },
    new Student() { StudentID = 5, StudentName = "Ron" , Age = 15 } 
};

IList<Standard> standardList = new List<Standard>() { 
    new Standard(){ StandardID = 1, StandardName="Standard 1"},
    new Standard(){ StandardID = 2, StandardName="Standard 2"},
    new Standard(){ StandardID = 3, StandardName="Standard 3"}
};

var groupJoin = from std in standardList 
                      join s in studentList 
                      on std.StandardID equals s.StandardID
                          into studentGroup
                      select new { 
                              Students = studentGroup , 
                              StandardName = std.StandardName 
                          };

foreach (var item in groupJoin)
{ 
    Console.WriteLine(item.StandarFulldName );

    foreach(var stud in item.Students)
        Console.WriteLine(stud.StudentName);
}

相关实例:

Dim groupJoin = From s In standardList
                Group Join stud In studentList 
                On stud.StandardID Equals s.StandardID
                    Into Group _
                Select _
                    StudentsGroup = Group,
                    StandardName = s.StandardName

运行结果:

Standard 1: 
John,
Moin,
Standard 2:
Bill,
Ram,
Standard 3:

在VB.Net中,InTo关键字将创建一组具有相同标准的所有学生,并将其分配给Group关键字。 所以,在投影结果中使用Group。

注意

匹配键选择器使用equals操作符。 ==无效。


版权声明:本站所有教程均为本站原创或翻译,转载请注明出处,请尊重他人劳动果实。请记住本站地址:www.yuanjiaocheng.net (猿教程) 作者:卿文刚
本文标题: C#环境
本文地址:http://www.yuanjiaocheng.net/Linq/linq-joining-operator-groupjoin.html