本篇介绍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语言等价的操作基本介绍完,组合这些操作能实现复杂的查询。
相关推荐
其中,`GroupBy`方法是LINQ中的一个重要部分,它用于将数据集根据一个或多个键进行分组,以便我们可以对每个分组进行进一步的操作。本文将深入探讨`GroupBy`方法的使用,包括其基本用法、多键分组以及在实际开发中的...
`GroupBy`操作符是LINQ中的一个关键部分,它允许我们按照一个或多个属性将数据集分组。例如,在给定的代码中,我们看到`GroupBy`被用来根据`TestId`和`TestName`属性对`TeamDto`对象进行分组: ```csharp var ...
废话不多说了,直接给大家贴代码了,具体代码如下所示: public class Person { public string FirstName{set;get;} public string LastName{set;get;} public Person(){} public Person(string firstName, ...
LINQ(Language Integrated Query,语言集成查询)是.NET框架中的一项重要特性,它为C#和Visual Basic等编程语言提供了内置的查询能力,使得开发者能够使用强类型、编译时检查以及直观的语法来处理各种数据源。...
Linq中GroupBy方法的使用总结 Linq 中的 GroupBy 方法是对数据进行分组的操作,通常用于对一个或多个字段进行分组,求其总和、均值等。下面我们来详细介绍 Linq 中 GroupBy 方法的使用。 一、基本使用 在 Linq 中...
用C#实现对DataTable的JOIN,GROUP BY,FILTER,UNIONALL,DISTINCT
C#在LINQ中使用GroupBy C#中的语言集成查询(Language Integrated Query,LINQ)是一个强大的查询语言,可以对数据进行筛选、排序、分组等操作。在LINQ中,GroupBy是一个非常重要的操作,它可以将数据分组,以便更...
强大的Go语言集成查询(LINQ)库。 用香草Go语言编写,没有依赖项! 使用迭代器模式完成延迟评估 可同时使用 支持通用功能,使您的代码更整洁,没有类型断言 支持数组,切片,地图,字符串,通道和自定义集合 ...
4. **其他Linq扩展**:除了基础的Linq用法,Linq还支持更复杂的查询操作,如分组(GroupBy)、连接(Join)、聚合(Aggregate)等。这些高级功能在处理复杂的数据分析任务时非常有用。 学习这些实例代码,可以帮助...
LINQ(Language Integrated Query,语言集成查询)是.NET框架中的一项重要特性,它为C#和Visual Basic等编程语言提供了内置的查询能力。LINQ允许开发者以一种与语言紧密结合的方式执行查询,使得代码更加简洁、易读...
这样,原本在SQL中才有的`select`、`from`、`where`、`group`等关键字,被引入到C#中,使得开发者可以更加自然地编写查询代码。 【LINQ查询的基本形式】 以示例代码为例,我们先创建一个`Book`类,包含书籍的相关...
查询表达式通常以关键字`from`开头,类似SQL的SELECT语句,而方法链则使用一系列扩展方法如`Select()`、`Where()`和`GroupBy()`等来构建查询。这两种方式都能够在编译时被转换成对应的数据库查询语句,确保了性能和...
group row by row.Field("Category") into categoryGroup orderby categoryGroup.Count() descending select new { Category = categoryGroup.Key, Count = categoryGroup.Count() }; ``` **LINQ to Objects** ...
2. **查询运算符**:除了查询表达式,LINQ还提供了一系列查询运算符,如`Where()`用于过滤数据,`Select()`用于转换数据,`OrderBy()`和`OrderByDescending()`用于排序,`GroupBy()`用于分组,`Join()`用于联接等。...
### LINQ之路——深入浅出理解LINQ #### 一、LINQ简介 **LINQ**(Language Integrated Query)是.NET Framework 3.5引入的一项重要技术特性,它将查询功能直接融入到C#和VB.NET等.NET编程语言中。通过LINQ,开发者...
在提供的项目文件中,`DynamicLinq.sln`是一个解决方案文件,包含了一个名为`DynamicLinq`的项目,很可能是用于实现动态LINQ查询的功能。`DataTable_RowToColumn`可能是一个示例项目,展示了如何将`DataTable`中的...