1. 程式人生 > >Linq中的連接(join)

Linq中的連接(join)

bject page blog 結構體類型 def efault [1] name software

Linq中連接主要有組連接、內連接、左外連接、交叉連接四種。各個用法如下。

註:本文內容主要來自《Linq實戰》,本例中用到的對象請見文章底部。

1、 組連接

組連接是與分組查詢是一樣的。即根據分組得到結果。 如下例,根據publisther分組得到結果。

使用組連接的查詢語句如下:

技術分享 //使用組連接
var GroupQuery = from publisher in SampleData.Publishers
join book in SampleData.Books
on publisher equals book.Publisher into publisherBooks
select new
{
PublisherName = publisher.Name,
Books = publisherBooks
}; 技術分享

與上邊等同的GroupBy語句如下:

技術分享 //使用Group
var QueryByGroup = from book in SampleData.Books
group book by book.Publisher into grouping
select new
{
PublisherName = grouping.Key.Name,
Books = grouping
}; 技術分享

2、內連接

內連接與SqL中inner join一樣,即找出兩個序列的交集。如下例找出book中的Publisher存在於SampleData.Publishers的資料。

內連接查詢語句如下:

技術分享 //join查詢語句
var joinQuery = from publisher in SampleData.Publishers
join book in SampleData.Books
on publisher equals book.Publisher
select new
{
PublisherName = publisher.Name,
BookName = book.Title
}; 技術分享

與上邊等同的查詢操作符語句如下:

技術分享 //join操作符語句
SampleData.Publishers.Join(
SampleData.Books, //join 對象
publisher => publisher, //外部的key
book => book.Publisher, //內部的key
(publisher, book) => new //結果
{
PublisherName = publisher.Name,
BookName = book.Title
}); 技術分享

3、左外連接

左外連接與SqL中left join一樣。如下例找出根據publisher中找出SampleData.Publishers中所有資料和book中存在於publisher的資料。

左外連接查詢語句如下:

技術分享 //left join, 為空時用default
var leftJoinQuerybyDefault = from publisher in SampleData.Publishers
join book in SampleData.Books
on publisher equals book.Publisher into publisherBooks
from book in publisherBooks.DefaultIfEmpty()
select new
{
PublisherName = publisher.Name,
BookName = (book == default(Book)) ? "no book" : book.Title
}; 技術分享

註:上例中使用了DefaultIfEmpty操作符,它能夠為實序列提供一個默認的元素。DefaultIfEmpty使用了泛型中的default關鍵字。default關鍵字對於引用類型將返回null,而對於值類型則返回0。對於結構體類型,則會根據其成員類型將它們相應地初始化為null(引用類型)或0(值類型)。

我們可以不使用default關鍵字,但在要DefaultIfEmpty中給定當空時的默認對象值。語句如下:

技術分享 //left join, 為空時使用默認對象
var leftJoinQuery = from publisher in SampleData.Publishers
join book in SampleData.Books
on publisher equals book.Publisher into publisherBooks
from book in publisherBooks.DefaultIfEmpty(
new Book { Title = "" } //設置為空時的默認值
)
select new
{
PublisherName = publisher.Name,
BookName = book.Title
}; 技術分享

4、交叉連接

交叉連接與SqL中Cross join一樣。如下例中找出SampleData.Publishers與SampleData.Books的交叉連接。

交叉連接查詢語句:

技術分享 var crossJoinQuery = from publisher in SampleData.Publishers
from book in SampleData.Books
select new
{
PublisherName = publisher.Name,
BookName = book.Title
}; 技術分享

查詢操作符語句:

技術分享 //不使用查詢表達式
SampleData.Publishers.SelectMany(publisher => SampleData.Books.Select(
book => new
{
PublisherName = publisher.Name,
BookName = book.Title
}
)); 技術分享

本像用到的對象:

技術分享 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]
}
};
} 技術分享

Linq中的連接(join)