使用的数据源类型:
static public class SampleData { static public Publisher[] Publishers = { new Publisher {Name="FunBooks"}, new Publisher {Name="Joe Publishing"}, new Publisher {Name="I Publisher"} }; static public Author[] Authors = { new Author {FirstName="Johnny", LastName="Good"}, new Author {FirstName="Graziella", LastName="Simplegame"}, new Author {FirstName="Octavio", LastName="Prince"}, new Author {FirstName="Jeremy", LastName="Legrand"} }; static public Subject[] Subjects = { new Subject {Name="Software development"}, new Subject {Name="Novel"}, new Subject {Name="Science fiction"} }; static public Book[] Books = { new Book { Title="Funny Stories", Publisher=Publishers[0], Authors=new[]{Authors[0], Authors[1]}, PageCount=101, Price=25.55M, PublicationDate=new DateTime(2004, 11, 10), Isbn="0-000-77777-2", Subject=Subjects[0] }, new Book { Title="LINQ rules", Publisher=Publishers[1], Authors=new[]{Authors[2]}, PageCount=300, Price=12M, PublicationDate=new DateTime(2007, 9, 2), Isbn="0-111-77777-2", Subject=Subjects[0] }, new Book { Title="C# on Rails", Publisher=Publishers[1], Authors=new[]{Authors[2]}, PageCount=256, Price=35.5M, PublicationDate=new DateTime(2007, 4, 1), Isbn="0-222-77777-2", Subject=Subjects[0] }, new Book { Title="All your base are belong to us", Publisher=Publishers[1], Authors=new[]{Authors[3]}, PageCount=1205, Price=35.5M, PublicationDate=new DateTime(2006, 5, 5), Isbn="0-333-77777-2", Subject=Subjects[2] }, new Book { Title="Bonjour mon Amour", Publisher=Publishers[0], Authors=new[]{Authors[1], Authors[0]}, PageCount=50, Price=29M, PublicationDate=new DateTime(1973, 2, 18), Isbn="2-444-77777-2", Subject=Subjects[1] } }; }
1、组连接
组连接是与分组查询是一样的。即根据分组得到结果。 如下例,根据publisther分组得到结果。
使用组连接的查询语句如下:
GridViewGroupJoin.DataSource = from publisher in SampleData.Publishers join book in SampleData.Books on publisher equals book.Publisher into publisherBooks select new { Publisher=publisher.Name, Books=publisherBooks }; GridViewGroupJoin.DataBind();
上述代码就是所谓的“组连接”。它将每个出版社的图书分组为PublisherBooks,并绑定到了一起。这段代码与下面代码运行结果一致。
var x = from book in SampleData.Books group book by book.Publisher into bookPublishers select new { Publisher = bookPublishers.Key.Name, books = bookPublishers };
2、内连接
内连接与SqL中inner join一样,即找出两个序列的交集。如下例找出book中的Publisher存在于SampleData.Publishers的资料。
内连接查询语句如下:
GridViewInnerJoin.DataSource = from publisher in SampleData.Publishers join book in SampleData.Books on publisher equals book.Publisher select new { Publisher=publisher.Name, Book=book.Title }; GridViewInnerJoin.DataBind();
内连接旨在找到两个序列的交集。经过内连接操作之后,满足指定条件且分别来自两个序列中的元素将被组合到一起,形成一个新的序列。Join操作符将基于元素中的Key的匹配情况,实现内连接。
3、左外连接
在内连接中,只有在两个待连接序列中均符合条件的组合才会出现在结果序列中。不过若是需要保留外部序列中的所有元素,而不管其是否有与之对应的、符合条件的内部序列元素存在,那么我们则要执行 左外连接 操作。
GridViewLeftOuterJoin.DataSource = from publisher in SampleData.Publishers join book in SampleData.Books on publisher equals book.Publisher into publisherBooks from book in publisherBooks.DefaultIfEmpty() select new { Publisher = publisher.Name, Book = book == default(Book) ? "(no books)" : book.Title }; GridViewLeftOuterJoin.DataBind();
DefaultIfEmpty()能够为空序列提供一个默认的元素。DefaultIfEmpty使用到了泛型的default关键词,对于引用类型将返回null,而对于值类型将返回0。对于结构体类型,则会根据其成员类型将他们对应的初始化为null或者0.
4、交叉连接
交叉连接将计算出两个序列中所有元素的笛卡尔积。结果序列将由一个序列中的每个元素和另一个序列中的每个元素的完全组合构成。结果序列中的元素的个数为两个源序列中的元素个数的积。
LINQ中的交叉连接并不是通过Join操作符实现的。在linq的术语中,交叉连接是指一类投影操作,可以通过SelectMany操作符或在查询表达式中使用多个from子句来实现。
GridViewCrossJoin.DataSource = from publisher in SampleData.Publishers from book in SampleData.Books select new { Correct = publisher == book.Publisher, Publisher = publisher.Name, Book = book.Title }; GridViewCrossJoin.DataBind();
SelectMany操作符方式:
SampleData.Publishers.SelectMany(publisher => SampleData.Books.Select( book => new { PublisherName = publisher.Name, BookName = book.Title } ));
LINQ IN ACTION读书笔记.