• Linq中连接


    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]
          }
        };
      }
  • 相关阅读:
    适配器模式(16)
    状态模式(15)
    用反射技术替换工厂种的switch分支(14)
    2017年目标与规划
    抽象工厂模式(13)
    观察者模式(12)
    建造者模式(11)
    TCP 可靠传输与流量控制的实现
    TCP报文段的首部格式
    TCP可靠传输的工作原理
  • 原文地址:https://www.cnblogs.com/sxhlf/p/7804878.html
Copyright © 2020-2023  润新知