LINQ 学习路程 -- 查询操作 Join

Join操作是将两个集合联合

Joining Operators Usage
Join 将两个序列连接并返回结果集
GroupJoin
根据key将两个序列连接返回,像是SQL中的Left

Join

Join操作两个集合,inner collection 和 outer collection

它返回一个集合(包含两个集合根据特定条件结合的所有元素),和SQL中的inner 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);

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);
IList<string> strList1 = new List<string>() {
    "One",
    "Two",
    "Three",
    "Four"
};

IList<string> strList2 = new List<string>() {
    "One",
    "Two",
    "Five",
    "Six"
};

var innerJoin = strList1.Join(strList2,
                      str1 => str1,
                      str2 => str2,
                      (str1, str2) => str1);
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; }
}
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 innerJoin = studentList.Join(// outer sequence
                      standardList,  // inner sequence
                      student => student.StandardID,    // outerKeySelector
                      standard => standard.StandardID,  // innerKeySelector
                      (student, standard) => new  // result selector
                                    {
                                        StudentName = student.StudentName,
                                        StandardName = standard.StandardName
                                    });

在上面的例子中,studentList是外部序列,因为先从它开始查询,Join的第一个参数是指定的内部序列,第二个和第三个参数指定对应的字段

外部序列的key选择器student => student.StandardID表明studentList中每个元素的StandardId字段必须与内部序列standard => standard.StandardID相对应

如果所有的key值相等则被包含在结果集中

最后一个参数是构建结果数据

查询语法

查询语法中的join和方法语法有些不同,它需要外部序列、内部序列、key选择器和结果选择器

from ... in outerSequence

join ... in innerSequence  

on outerKey equals innerKey

select ...

GroupJoin

GroupJoin和Join是一样的除了GroupJoin返回一个Group(根据特定的group key)

GroupJoin根据key联合两个序列并根据key分组

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

查询语法

from ... in outerSequence

join ... in innerSequence  

on outerKey equals innerKey

into groupedCollection    

select ...
时间: 2024-11-27 18:19:44

LINQ 学习路程 -- 查询操作 Join的相关文章

LINQ 学习路程 -- 查询操作 OrderBy &amp; OrderByDescending

Sorting Operator Description OrderBy 通过给定的字段进行升序 降序 排序 OrderByDescending 通过给定字段进行降序排序,仅在方法查询中使用 ThenBy 第二级升序排序,仅在方法查询中使用 ThenByDescending 第二级降序排序,仅在方法查询中使用 Reverse 反转集合,仅在方法查询中使用 IList<Student> studentList = new List<Student>() { new Student()

LINQ 学习路程 -- 查询操作 Expression Tree

表达式树就像是树形的数据结构,表达式树中的每一个节点都是表达式, 表达式树可以表示一个数学公式如:x<y.x.<.y都是一个表达式,并构成树形的数据结构 表达式树使lambda表达式的结构变得透明清楚, Expression<Func<Student, bool>> isTeenAgerExpr = s => s.age > 12 && s.age < 20; 编译器将上面的表达式翻译成下面的表达式树 Expression.Lambda

LINQ 学习路程 -- 查询操作 where

1.where Filtering Operators Description Where Returns values from the collection based on a predicate function OfType Returns values from the collection based on a specified type. However, it will depend on their ability to cast to a specified type.

LINQ 学习路程 -- 查询操作 Deferred Execution of LINQ Query 延迟执行

延迟执行是指一个表达式的值延迟获取,知道它的值真正用到. 当你用foreach循环时,表达式才真正的执行. 延迟执行有个最重要的好处:它总是给你最新的数据 实现延迟运行 你可以使用yield关键字实现延迟加载 public static class EnumerableExtensionMethods { public static IEnumerable<Student> GetTeenAgerStudents(this IEnumerable<Student> source)

LINQ 学习路程 -- 查询操作 OfType

OfType操作根据集合中的元素是否是给定的类型进行筛选 IList mixedList = new ArrayList(); mixedList.Add(0); mixedList.Add("One"); mixedList.Add("Two"); mixedList.Add(3); mixedList.Add(new Student() { StudentID = 1, StudentName = "Bill" }); var stringR

LINQ 学习路程 -- 查询操作 let into关键字

IList<Student> studentList = new List<Student>() { new Student() { StudentID = 1, StudentName = "John", Age = 18 } , new Student() { StudentID = 2, StudentName = "Steve", Age = 21 } , new Student() { StudentID = 3, StudentN

LINQ 学习路程 -- 查询操作 GroupBy ToLookUp

Grouping Operators Description GroupBy GroupBy操作返回根据一些键值进行分组,每组代表IGrouping<TKey,TElement>对象 ToLookup ToLookup is the same as GroupBy; the only difference is the execution of GroupBy is deferred whereas ToLookup execution is immediate. IList<Stude

LINQ 学习路程 -- 查询操作 ThenBy &amp; ThenByDescending

IList<Student> studentList = new List<Student>() { new Student() { StudentID = 1, StudentName = "John", Age = 18 } , new Student() { StudentID = 2, StudentName = "Steve", Age = 15 } , new Student() { StudentID = 3, StudentN

LINQ 学习路程 -- 查询操作 Quantifier Operators All Any Contain

Operator Description All 判断所有的元素是否满足条件 Any 判断存在一个元素满足条件 Contain 判断是否包含元素 IList<Student> studentList = new List<Student>() { new Student() { StudentID = 1, StudentName = "John", Age = 18 } , new Student() { StudentID = 2, StudentName