Linq 中 Join 的用法


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]
      }
    };
  }
復制代碼

 

轉載於:http://www.cnblogs.com/scottckt/archive/2010/08/11/1797716.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM