LINQ使用连接(1、组连接 2、内连接 3、左外连接 4、交叉连接)
转载:http://blog.csdn.net/lwllai/article/details/46877311
复习一下LINQ的连接操作:
- static public class SampleData
- {
- static public Student[] Students =
- {
- new Student {Name="Richard"},
- new Student {Name="Joe"},
- new Student {Name="Tom"}
- };
- static public Subject[] Subjects =
- {
- new Subject {Name="语文"},
- new Subject {Name="数学"},
- new Subject {Name="英语"}
- };
- static public Book[] Books =
- {
- new Book {
- Title="人教版语文",
- PublicationDate=new DateTime(2004, 11, 10),
- Subject=Subjects[0]
- },
- new Book {
- Title="苏教版语文",
- PublicationDate=new DateTime(2007, 9, 2),
- Subject=Subjects[0]
- },
- new Book {
- Title="人教版数学",
- PublicationDate=new DateTime(2007, 4, 1),
- Subject=Subjects[1]
- },
- new Book {
- Title="人教版英语",
- PublicationDate=new DateTime(2006, 5, 5),
- Subject=Subjects[2]
- },
- new Book {
- Title="苏教版数学",
- PublicationDate=new DateTime(1973, 2, 18),
- Subject=Subjects[1]
- }
- };
- }
1、组连接组连接是与分组查询是一样的。即根据分组得到结果。 如下例,根据Subject科目进行分组得到结果。使用组连接的查询语句如下:
- var query = from sub in SampleData.Subjects
- join book in SampleData.Books on sub equals book.Subject into AllBooks
- select new { Subject = sub.Name, Books = AllBooks };
上述代码就是所谓的“组连接”。它将每个出版社的科目分组为AllBooks,并绑定到了一起。这段代码与下面代码运行结果一致。
- var x = from book in SampleData.Books
- group book by book.Subject
- into AllBooks
- select new { Subject = AllBooks.Key.Name, books = AllBooks };
2、内连接
内连接与SqL中inner join一样,即找出两个序列的交集。如下例找出book中的Subject存在于SampleData.Subjects的资料。内连接查询语句如下:
- var query = from sub in SampleData.Subjects
- join book in SampleData.Books on sub equals book.Subject
- select new { subject=sub.Name, Book=book.Title };
内连接旨在找到两个序列的交集。经过内连接操作之后,满足指定条件且分别来自两个序列中的元素将被组合到一起,形成一个新的序列。Join操作符将基于元素中的Key的匹配情况,实现内连接。
3、左外连接
在内连接中,只有在两个待连接序列中均符合条件的组合才会出现在结果序列中。不过若是需要保留外部序列中的所有元素,而不管其是否有与之对应的、符合条件的内部序列元素存在,那么我们则要执行 左外连接 操作。
- var query = from sub in SampleData.Subjects
- join book in SampleData.Books on sub equals book.Subject into AllBooks
- from book in AllBooks.DefaultIfEmpty()
- select new {
- subject = sub.Name,
- Book = book == default(Book) ? "(no books)" : book.Title
- };
DefaultIfEmpty()能够为空序列提供一个默认的元素。DefaultIfEmpty使用到了泛型的default关键词,对于引用类型将返回null,而对于值类型将返回0。对于结构体类型,则会根据其成员类型将他们对应的初始化为null或者0.
4、交叉连接
交叉连接将计算出两个序列中所有元素的笛卡尔积。结果序列将由一个序列中的每个元素和另一个序列中的每个元素的完全组合构成。结果序列中的元素的个数为两个源序列中的元素个数的积。
LINQ中的交叉连接并不是通过Join操作符实现的。在linq的术语中,交叉连接是指一类投影操作,可以通过SelectMany操作符或在查询表达式中使用多个from子句来实现。
- var query = from stu in SampleData.Students
- from book in SampleData.Books
- select new {
- Student = stu.Name,
- BookName = book.Title
- };
- var query = SampleData.Students.SelectMany(stu => SampleData.Books.Select(
- book => new
- {
- Student = stu.Name,
- BookName = book.Title
- }
- ));