zoukankan      html  css  js  c++  java
  • Linq 学习(1) Group & Join--网摘

    Group
    Group是进行分组操作,同SQL中的Group By类似。
    原型如下:

    public static IEnumerable<IGrouping<TKey, TSource>> GroupBy<TSource, TKey>( 
        
    this IEnumerable<TSource> source, 
        Func
    <TSource, TKey> keySelector)


    它有几个重载,返回类型有两种:IEnumerable<IGrouping<TKey, TSource>> 和 IEnumerable<TResult>。
    返回类型为:IEnumerable<IGrouping<TKey, TSource>>
    示例:
    返回按学号分组学生的成绩

    var result = from score in DataSource.Scores 
                 
    group score by score.StudentID into scoreGroup 
                 select scoreGroup;


    scoreGroup为IGrouping<TKey, TSource>类型,返回结果为IEnumerable<IGrouping<TKey, TSource>>,既集合的集合,因此输出时需用双重循环。
    IGrouping<TKey, TElement>接口定义为:

    public interface IGrouping<TKey, TElement> : IEnumerable<TElement>, IEnumerable 
    { 
        TKey Key { 
    get; } 
    }

    其中Key为分组依据的字段。

    foreach (var group in result) 
    { 
        
    //输出分组依据的字段 
        Console.WriteLine(" Student ID:" + group.Key); 

        
    // 输出组内成员 
        foreach (var score in group) 
        { 
            Console.WriteLine(score); 
        } 
    } 

    // result: 
    // Student ID:1 
    // Student ID:1,Course ID:1,Score:78 
    // Student ID:1,Course ID:2,Score:60 
    // ... 

    // Student ID:2 
    // Student ID:2,Course ID:1,Score:59 
    // ...


    等效的扩展方法调用实现为:

    var result = DataSource.Scores.GroupBy(score => score.StudentID);


    返回类型为:IEnumerable<TResult>
    对分组结果进行一些包装,如包装为匿名类型。
    返回按学号分组学生的成绩

    var result = from score in DataSource.Scores 
                 
    group score by score.StudentID into scoreGroup 
                 select 
    new { StudentID = scoreGroup.Key, Group = scoreGroup };


    匿名类型中Group为IGrouping<TKey, TSource>类型。
    等效的扩展方法调用实现为:

    var result = DataSource.Scores.GroupBy(score => score.StudentID, 
        (key, 
    group) => new { StudentID = key, Group = group });


    其他一些重载使用方法类似。

    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)


    从Join方法原型可以看出其使用方法。

    内连接
    选择左右两侧集合都含有相对应的元素。
    示例:
    查询学生的姓名、学科、成绩。

    var result = from score in DataSource.Scores 
                 
    join student in DataSource.Students on score.StudentID equals student.StudentID 
                 
    join course in DataSource.Courses on score.CourseID equals course.CourseID 
                 select 
    new { StudentName = student.Name, CourseName = course.CourseName, ScoreValue = score.Value }; 
    // result 
    // { StudentName = Andy, CourseName = C Language, ScoreValue = 78 } 
    // { StudentName = Andy, CourseName = Biophysics, ScoreValue = 60 } 
    // ... 
    // { StudentName = Bill, CourseName = C Language, ScoreValue = 59 } 
    // { StudentName = Cindy, CourseName = Biophysics, ScoreValue = 60 } 
    // ...


    等效的扩展方法调用实现为:

    var result = 
        DataSource.Scores.Join( 
        DataSource.Students, 
        score 
    => score.StudentID, 
        student 
    => student.StudentID, 
        (score, student) 
    => new { StudentName = student.StudentID, ScoreValue = score.Value, CourseID = score.CourseID }) 
        .Join(DataSource.Courses, 
        scostu 
    => scostu.CourseID, 
        course 
    => course.CourseID, 
        (scostu, course) 
    => new { StudentName = scostu.StudentName, CourseName = course.CourseName, ScoreValue = scostu.ScoreValue }); 


    左外连接
    当右侧的连接的右侧没有左侧对应的元素时,内连接会忽略左侧元素。要想保留左侧元素,可以使用做外连接。右侧被置为默认值,如:引用类型被置为空。
    示例:

    var result = 
        
    from student in DataSource.Students2 
        
    join score in DataSource.Scores on student.StudentID equals score.StudentID into Scores 
        
    from score in Scores.DefaultIfEmpty() 
        select 
    new { student = student, score = score == default(Score) ? 0 : score.Value }; 
    // result: 
    // { student = Student ID:5,Student Name:Erik, score = 78 } 
    // { student = Student ID:6,Student Name:Frank, score = 0 } 

    等效的扩展方法调用实现为: 
    var result = 
        DataSource.Students2.GroupJoin( 
        DataSource.Scores, 
        student 
    => student.StudentID, 
        score 
    => score.StudentID, 
        (student, Scores) 
    => new { student = student, Scores = Scores }) 
        .SelectMany(
    group => group.Scores.DefaultIfEmpty(), 
        (
    group, score) => new { student = group.student, score = (score == null) ? 0.0 : score.Value });


    笛卡尔积
    集合中的元素交错连接。
    示例:统计学生课程成绩时的模板。

    var result = from student in DataSource.Students 
                 
    from course in DataSource.Courses 
                 select 
    new { StudentName = student.Name, CourseName = course.CourseName, ScoreValue = (double?)null }; 
    // result: 
    // { StudentName = Andy, CourseName = C Language, ScoreValue =  } 
    // { StudentName = Andy, CourseName = Biophysics, ScoreValue =  } 
    // ... 
    // { StudentName = Bill, CourseName = C Language, ScoreValue =  } 
    // ... 
    // { StudentName = Cindy, CourseName = Fundamentals of Compiling, ScoreValue =  } 
    // ... 

    等效的扩展方法调用实现为: 
    var result = DataSource.Students.SelectMany( 
        student 
    => DataSource.Courses 
            .Select( 
            course 
    => 
                
    new { StudentName = student.Name, CourseName = course.CourseName, ScoreValue = (double?)null }));


    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) 

    // result: 
    // Andy 
    // 1----78 
    // 2----60 
    // ... 
    // Bill 
    // 1----59 
    // ... 
    // Cindy 
    // 2----60 
    // ...


    相当于组合了Group操作和Join操作。等效的操作如下:

    var result = from item in 
                     (
    from student in DataSource.Students 
                      
    join score in DataSource.Scores on student.StudentID equals score.StudentID 
                      select 
    new { StudentName = student.Name, CourseID = score.CourseID, Value = score.Value }) 
                 
    group item by item.StudentName into Group 
                 select 
    new { StudentName = Group.Key, Group = Group };
  • 相关阅读:
    mysql总结
    spirngmvc整合mybatis实现CRUD
    java lesson09总结
    Java lesson08 Homework
    java Lesson08总结
    【DFS】bzoj2435 [Noi2011]道路修建
    【BFS】bzoj2252 [2010Beijing wc]矩阵距离
    【BFS】bzoj1054 [HAOI2008]移动玩具
    【搜索】bzoj3109 [cqoi2013]新数独
    【搜索】【约数个数定理】[HAOI2007]反素数ant
  • 原文地址:https://www.cnblogs.com/findchance/p/3159334.html
Copyright © 2011-2022 走看看