linq group join
本篇介绍Linq的Group和Join操作,继续使用《Linq 学习(3) 语法结构》中介绍的数据源。
Group
Group是进行分组操作,同SQL中的Group By类似。
原型如下:
this IEnumerable<TSource> source,
Func<TSource, TKey> keySelector)
它有几个重载,返回类型有两种:IEnumerable<IGrouping<TKey, TSource>> 和 IEnumerable<TResult>。
返回类型为:IEnumerable<IGrouping<TKey, TSource>>
示例:
返回按学号分组学生的成绩
group score by score.StudentID into scoreGroup
select scoreGroup;
scoreGroup为IGrouping<TKey, TSource>类型,返回结果为IEnumerable<IGrouping<TKey, TSource>>,既集合的集合,因此输出时需用双重循环。
IGrouping<TKey, TElement>接口定义为:
{
TKey Key { get; }
}
其中Key为分组依据的字段。
{
//输出分组依据的字段
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
// ...
等效的扩展方法调用实现为:
返回类型为:IEnumerable<TResult>
对分组结果进行一些包装,如包装为匿名类型。
返回按学号分组学生的成绩
group score by score.StudentID into scoreGroup
select new { StudentID = scoreGroup.Key, Group = scoreGroup };
匿名类型中Group为IGrouping<TKey, TSource>类型。
等效的扩展方法调用实现为:
(key, group) => new { StudentID = key, Group = group });
其他一些重载使用方法类似。
Join
连接操作。
this IEnumerable<TOuter> outer,
IEnumerable<TInner> inner,
Func<TOuter, TKey> outerKeySelector,
Func<TInner, TKey> innerKeySelector,
Func<TOuter, TInner, TResult> resultSelector)
从Join方法原型可以看出其使用方法。
内连接
选择左右两侧集合都含有相对应的元素。
示例:
查询学生的姓名、学科、成绩。
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 }
// ...
等效的扩展方法调用实现为:
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 });
左外连接
当右侧的连接的右侧没有左侧对应的元素时,内连接会忽略左侧元素。要想保留左侧元素,可以使用做外连接。右侧被置为默认值,如:引用类型被置为空。
示例:
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 });
笛卡尔积
集合中的元素交错连接。
示例:统计学生课程成绩时的模板。
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
连接分组。
方法原型为:
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操作。等效的操作如下:
(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语言等价的操作基本介绍完,组合这些操作能实现复杂的查询。
linq group join的更多相关文章
- Linq中join & group join & left join 的用法
Linq中join & group join & left join 的用法 2013-01-30 11:12 12154人阅读 评论(0) 收藏 举报 分类: C#(14) 文章 ...
- Join, Group Join
Linq的 Join对应SQL中的inner join,当左右两张表有匹配数据时才返回一条记录: Linq的 Group Join对应SQL中的LEFT OUTER JOIN,即使右表中没有匹配,也从 ...
- EF INNER JOIN,LEFT JOIN,GROUP JOIN
IQueryable<TOuter>的扩展方法中提供了 INNER JOIN,GROUP JOIN但是没有提供LEFT JOIN GROUP JOIN适用于一对多的场景,如果关联的GROU ...
- EF 里的 join and Group Join
join ); pageCount = _db.Orders.Count(); return _db.Orders.OrderByDescending(c=>c.ID).Skip(skip).T ...
- Using LINQ Group By and String.Join() / Aggregate() in Entity Framework 3.5
linq to sql 的时候,有时候需要用到 先group 然后来个 aggregate 串连一下值, 但会总会出错,说不识别 aggregate 或者 string.join 方法 搜遍网络 一 ...
- LINQ学习笔记 Join 与 Group join
LINQ中的Join对应T-SQL中的内连接,并无左连接的方法,当然也没有右连接. 要达成Left join必须依靠GroupJoin来完成. GroupJoin顾名思义就是先集团在做加入,加入的不同 ...
- linq 实现group by 不使用group关键字 等同lambad表达式中的group join 查询一对多关系
return from orderInfo in orderEntity.x_s_orderInfo join oState in orderEntity.x_s_oStatuInfo on orde ...
- linq group by max 多表链接实例
SELECT s.* FROM dbo.ERG_TipOffsInfo s, (SELECT Data,MAX(Createtime) max_Time FROM dbo.ERG_TipOffsInf ...
- Linq 中 Join 的用法
Linq中连接主要有组连接.内连接.左外连接.交叉连接四种.各个用法如下. 注:本文内容主要来自<Linq实战>,本例中用到的对象请见文章底部. 1. 组连接 组连接是与分组查询是一样的. ...
随机推荐
- Spring注解@PostConstruct与@PreDestroy
关于在spring 容器初始化 bean 和销毁前所做的操作定义方式有三种: 第一种:通过@PostConstruct 和 @PreDestroy 方法 实现初始化和销毁bean之前进行的操作 第二 ...
- Java算法-冒泡排序
冒泡排序是一种简单的排序算法.它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来.走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成.这个算法的名字 ...
- 使用iframe 或frameset框架退出不成功
iframe .frameset框架有时登录界面加载在框架当中,但我们想直接到登录界面,这时我们可以使用js来实现.if(window!=top) { top.location.href=locati ...
- c#读取excel
Provider根据实际EXCEL的版本来设置,推荐使用ACE接口来读取.需要Access database Engine. 注意修改注册表以下两项的值为0.否则导入EXCEL当单元格内字符长度超过2 ...
- Java容器之旅:容器基础知识总结
下图展示了Java容器类库的完备图,包括抽象类和遗留构件(不包括Queue的实现). 常用的容器用黑色粗线框表示,点线框表示接口,虚线框表示抽象类,实线框表示类,空心箭头表示实现关系.Produce表 ...
- linux永久更改eth0的ip地址后仍然ping不通过
编辑文件/etc/sysconfig/network-scripts/ifcfg-eth0 引用:DEVICE=eth0 //设备名称,不要修改 BOOTPROTO=static //不要修改 BRO ...
- 【bzoj3158】 千钧一发
http://www.lydsy.com/JudgeOnline/problem.php?id=3158 (题目链接) 题意 给出n个装置,每个装置i有一个特征值a[i]和一个能量值b[i],要求选出 ...
- Windows Server 2012及以上安装IIS的步骤
已经和2008安装时有着明显区别,如题的安装步骤如下: 这里需要注意的是,选择了[Web 服务器(IIS)支持]后可能会弹出选择的界面,到时也一起全选,这里由于是已经安装了,所以没弹出. 说明:上面根 ...
- 针对CMS中的tag标签理解
针对CMS的tag标签有以下解释: 什么tag标签? TAG标签是一种由自定义的一种标签,要比分类更加的准确,可以概括文章主要内容的关键词. 运用TAG标签,可以使网站的文章更容易被搜索引擎检索到.百 ...
- oracle11g dataguard 安装手册(转)
文章转自:http://www.cnblogs.com/tippoint/archive/2013/04/18/3029019.html 一.前言: 网络上关于dataguard的配置文章很多,但 ...