作者:小乌龟和小土鳖 | 来源:互联网 | 2024-12-24 16:16
join 子句可用于将来自不同源序列并且在对象模型中没有直接关系的元素相关联。 唯一的要求是每个源中的元素需要共享某个可以进行比较以判断是否相等的值。测试数据代码 #region TestData
join 子句可用于将来自不同源序列并且在对象模型中没有直接关系的元素相关联。 唯一的要求是每个源中的元素需要共享某个可以进行比较以判断是否相等的值。
测试数据代码
#region TestData
public class Student
{
public string StudentName;
public int GradeId;
}
public class Grade
{
public int ID;
public string GradeName;
}
List students = new List()
{
new Student {StudentName="zs", GradeId =1},
new Student {StudentName="ls", GradeId = 1},
new Student {StudentName="ww", GradeId = 2}
};
List grades = new List()
{
new Grade {ID = 1, GradeName ="一年级"},
new Grade {ID = 2, GradeName ="二年级"},
new Grade {ID = 3, GradeName ="三年级"}
};
#endregion
内连接
内部同等连接,下面为演示代码,缺少了三年级
void Innerjoin ()
{
var innerQuery = from grade in grades
join student in students on grade.ID equals student.GradeId
select new { StudentName = student.StudentName, GradeName = grade.GradeName };
foreach (var item in innerQuery)
{
Console.WriteLine($"班级:{item.GradeName},有学生{item.StudentName}");
}
}
分组连接
分组联接会生成分层的结果序列,该序列将左侧源序列中的元素与右侧源序列中的一个或多个匹配元素相关联。 分组联接没有等效的关系术语;它本质上是一个对象数组序列。
如果在右侧源序列中找不到与左侧源中的元素相匹配的元素,则 join 子句会为该项生成一个空数组。 因此,分组联接基本上仍然是一种内部同等联接,区别在于分组联接将结果序列组织为多个组。
void Groupjoin()
{
var innerQuery = from grade in grades
join student in students on grade.ID equals student.GradeId into student_grade
select new { StudentData = from student2 in student_grade orderby student2.GradeId select student2 , GradeName = grade.GradeName };
foreach (var item in innerQuery)
{
Console.WriteLine("班级内有哪些人:");
foreach (var studentItem in item.StudentData)
{
Console.WriteLine($"班级:{item.GradeName},有学生{studentItem.StudentName}");
}
}
}
从上图可以看到,多加了一句前面的打印,这个 关于三年级的数组肯定是存在的,但是是空的数据,如果没有数据,得到的结果就跟内连接一致。
左外连接
在左外部联接中,将返回左侧源序列中的所有元素,即使右侧序列中没有其匹配元素也是如此。 若要在 LINQ 中执行左外部联接,请结合使用 DefaultIfEmpty 方法与分组联接,指定要在某个左侧元素不具有匹配元素时生成的默认右侧元素。 可以使用 null 作为任何引用类型的默认值,也可以指定用户定义的默认类型。
void LeftOutJoin()
{
var innerQuery = from grade in grades
join student in students on grade.ID equals student.GradeId into student_grade
from studentData in student_grade.DefaultIfEmpty(new Student { StudentName = "没有学生哦!" })
select new { StudentData = studentData, GradeName = grade.GradeName };
foreach (var item in innerQuery)
{
Console.WriteLine($"班级:{item.GradeName},有学生{item.StudentData.StudentName}");
}
}
从上面看到左外连接,默认出一个值,可以防止没有数组出现问题。