LINQ使用连接(1、组连接 2、内连接 3、左外连接 4、交叉连接)

首先呢,今天在数据库中写好了笛卡尔连接,后面要改写成LINQ的方式。突然瞬间蒙了,写多了JOIN却忘了怎么去写交叉连接(笛卡尔连接)。

顺便复习一下LINQ的连接操作:

  1. static public class SampleData  
  2.     {  
  3.         static public Student[] Students =  
  4.         {  
  5.           new Student {Name="Richard"},  
  6.           new Student {Name="Joe"},  
  7.           new Student {Name="Tom"}  
  8.         };  
  9.   
  10.         static public Subject[] Subjects =  
  11.         {  
  12.           new Subject {Name="语文"},  
  13.           new Subject {Name="数学"},  
  14.           new Subject {Name="英语"}  
  15.         };  
  16.         static public Book[] Books =  
  17.         {  
  18.           new Book {  
  19.             Title="人教版语文",  
  20.             PublicationDate=new DateTime(2004, 11, 10),  
  21.             Subject=Subjects[0]  
  22.           },  
  23.           new Book {  
  24.             Title="苏教版语文",         
  25.             PublicationDate=new DateTime(2007, 9, 2),  
  26.             Subject=Subjects[0]  
  27.           },  
  28.           new Book {  
  29.             Title="人教版数学",  
  30.             PublicationDate=new DateTime(2007, 4, 1),  
  31.             Subject=Subjects[1]  
  32.           },  
  33.           new Book {  
  34.             Title="人教版英语",  
  35.             PublicationDate=new DateTime(2006, 5, 5),  
  36.             Subject=Subjects[2]  
  37.           },  
  38.           new Book {  
  39.             Title="苏教版数学",  
  40.             PublicationDate=new DateTime(1973, 2, 18),  
  41.             Subject=Subjects[1]  
  42.           }  
  43.         };  
  44.     }  
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科目进行分组得到结果。使用组连接的查询语句如下:

  1. var query = from sub in SampleData.Subjects  
  2.                         join book in SampleData.Books on sub equals book.Subject into AllBooks  
  3.                         select new { Subject = sub.Name, Books = AllBooks };  
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,并绑定到了一起。这段代码与下面代码运行结果一致。

  1. var x = from book in SampleData.Books  
  2.                     group book by book.Subject  
  3.                     into AllBooks  
  4.                     select new { Subject = AllBooks.Key.Name, books = 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的资料。内连接查询语句如下:

  1. var query = from sub in SampleData.Subjects  
  2.       join book in SampleData.Books on sub equals book.Subject  
  3.       select new { subject=sub.Name, Book=book.Title };  
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、左外连接
  在内连接中,只有在两个待连接序列中均符合条件的组合才会出现在结果序列中。不过若是需要保留外部序列中的所有元素,而不管其是否有与之对应的、符合条件的内部序列元素存在,那么我们则要执行 左外连接  操作。

  1. var query = from sub in SampleData.Subjects  
  2.           join book in SampleData.Books on sub equals book.Subject into AllBooks  
  3.           from book in AllBooks.DefaultIfEmpty()  
  4.           select new {  
  5.             subject = sub.Name,  
  6.             Book = book == default(Book) ? "(no books)" : book.Title  
  7.           };  
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子句来实现。

  1. var query = from stu in SampleData.Students  
  2.           from book in SampleData.Books  
  3.           select new {  
  4.             Student = stu.Name,  
  5.             BookName = book.Title  
  6.           };  
var query = from stu in SampleData.Students
		  from book in SampleData.Books
		  select new {
			Student = stu.Name,
			BookName = book.Title
		  };
  1. var query = SampleData.Students.SelectMany(stu => SampleData.Books.Select(  
  2.                             book => new  
  3.                             {  
  4.                                 Student = stu.Name,  
  5.                                 BookName = book.Title  
  6.                             }  
  7.                             ));  
var query = SampleData.Students.SelectMany(stu => SampleData.Books.Select(
                            book => new
                            {
                                Student = stu.Name,
                                BookName = book.Title
                            }
                            ));

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值