`
sangei
  • 浏览: 329032 次
  • 性别: Icon_minigender_1
  • 来自: 西安
社区版块
存档分类
最新评论

linq group

阅读更多

本篇介绍Linq的Group和Join操作,继续使用《Linq 学习(3) 语法结构》中介绍的数据源。

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("\nStudent 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 };


结束语
到现在,Linq与SQL语言等价的操作基本介绍完,组合这些操作能实现复杂的查询。 

分享到:
评论

相关推荐

    解决C#中Linq GroupBy 和OrderBy失效的方法

    最近发现了一个问题,在服务器端的Linq GroupBy 和OrderBy居然不管用,后来终于解决了所以现在分享给大家,有需要的朋友们可以参考借鉴。

    Linq Grouping GroupBy 用法详解

    Linq Grouping GroupBy 用法详解 Linq Grouping GroupBy 用法详解

    C# 中的GroupBy的动态拼接问题及GroupBy用法介绍

    废话不多说了,直接给大家贴代码了,具体代码如下所示: public class Person { public string FirstName{set;get;} public string LastName{set;get;} public Person(){} public Person(string firstName, ...

    linq小案例

    linq小案例

    go-linq:Go中的.NET LINQ功能

    强大的Go语言集成查询(LINQ)库。 用香草Go语言编写,没有依赖项! 使用迭代器模式完成延迟评估 可同时使用 支持通用功能,使您的代码更整洁,没有类型断言 支持数组,切片,地图,字符串,通道和自定义集合 ...

    LINQ to SQL手册

    LINQ to SQL语句(6)之Group By/Having LINQ to SQL语句(7)之Exists/In/Any/All/Contains LINQ to SQL语句(8)之Concat/Union/Intersect/Except LINQ to SQL语句(9)之Top/Bottom和Paging和SqlMethods LINQ to SQL语句...

    C#在LINQ中使用GroupBy

    主要介绍了C#在LINQ中如何使用GroupBy,帮助大家更好的理解和学习c#,感兴趣的朋友可以了解下

    Linq中GroupBy方法的使用总结.

    Linq中GroupBy方法的使用总结.

    走进Linq 走进Linq

    select,from,where,group等关键字本来只是在SQL里出现,现在把它们引入到C#这些常规编程语言中。 那C#等是如何做到的呢?是在CLR底层支持的么?不是。既然“编译器”可以将C#编译成MSIL,那为什么编译不能干更多一点...

    LINQ vb.net - Sample Queries实例

    很多常用的Linq写法,基于Vb.net,本人收获良多 LinqSamples LinqToSQLSamples LinqToXMLSamples LinqToDataSetSamples 举例:Linq to sql Dim categories = From prod In db.Products _ Group By Key = New With ...

    LINQ演示程序,供新手使用

    一个简单的LINQ演示程序,供新手使用。演示了LINQ的查询功能,如基本查询,条件查询,group by等。LINQ不是一种语言,不能单独用来开发。 LINQ体现的是面向对象思想:源数据时对象,查询结果是对象

    Linq教程,快速查询

    LINQ的语义: from 临时变量 in 集合对象或数据库对象 where 条件表达式 [order by条件] select 临时变量中被查询的值 [group by 条件] LINQ的查询返回值的类型是临时变量的类型,可能是一个对象也可能是一个集合。...

    LINQ入门及应用 3/13

     3.5 group子句  3.5.1 IGrouping泛型接口  3.5.2 分组查询  3.6 into子句  3.7 排序子句  3.7.1 OrderBy和OrderByDescending  3.7.2 ThenBy和ThenByDescending  3.8 let子句  3.9 join子句  3.10 小结 第...

    LINQ_to_SQL语法及实例大全

    LINQ to SQL语句(6)之Group By/Having 23 Group By/Having操作符 23 1.简单形式: 23 2.Select匿名类 : 24 3.最大 值 25 4.最小 值 26 5.平均 值 26 6.求和 26 7.计数 27 8.带条件计数 27 9.Where限制 28 10.多列...

    LINQ入门及应用 11/13

     3.5 group子句  3.5.1 IGrouping泛型接口  3.5.2 分组查询  3.6 into子句  3.7 排序子句  3.7.1 OrderBy和OrderByDescending  3.7.2 ThenBy和ThenByDescending  3.8 let子句  3.9 join子句  3.10 小结 第...

    LINQ入门及应用 8/13

     3.5 group子句  3.5.1 IGrouping泛型接口  3.5.2 分组查询  3.6 into子句  3.7 排序子句  3.7.1 OrderBy和OrderByDescending  3.7.2 ThenBy和ThenByDescending  3.8 let子句  3.9 join子句  3.10 小结 第...

    LINQ入门及应用 1/13

     3.5 group子句  3.5.1 IGrouping泛型接口  3.5.2 分组查询  3.6 into子句  3.7 排序子句  3.7.1 OrderBy和OrderByDescending  3.7.2 ThenBy和ThenByDescending  3.8 let子句  3.9 join子句  3.10 小结 第...

    LINQ入门及应用 10/13

     3.5 group子句  3.5.1 IGrouping泛型接口  3.5.2 分组查询  3.6 into子句  3.7 排序子句  3.7.1 OrderBy和OrderByDescending  3.7.2 ThenBy和ThenByDescending  3.8 let子句  3.9 join子句  3.10 小结 第...

Global site tag (gtag.js) - Google Analytics