LINQ之查询语法—join子句

LINQ之查询语法--from子句中,我们介绍了如何通过多个from子句进行联接操作,下面我们来介绍专门用于联接操作的关键字:join

join主要用于根据不同的数据源的某个元素进行判断是否相等以达到将2个数据源联接在一起的目的。

在join子句中,必须使用equals关键字来比较指定的键是否相等。

join子句主要有三种常见的联接类型:

1)内部联接,与SQL的inner join类似

2)分组联接,含有into表达式join子句

3)左外部联接,与SQL的left join类似

 

1)我们来看看内部联接的例子:

 

var productList = from category in categories
                  join product in products on category.Id equals product.CategoryId 
                  select new { category.Name, product.ProductName };

 

 

对比一下我们用多个from子句进行联接的区别:

 

var productList = from category in categories
                  from product in products
                  where product.CategoryId == category.Id
                  select new {category.Name, product.ProductName};

 

 

需要注意的是equals是区分大小写的,如apple和Apple是不会equal的。

 

2)分组联接:

分组联接用到了into子句,into的意思是将join的内容暂存起来,并且可用于后面的操作,也可以直接作为select返回回来。

我们来看2个例子:

 

List<Category> categories = new List<Category>
                                            {
                                                new Category{Id = 1,Name = "Food"},
                                                new Category{Id = 2,Name = "Toys"},
                                                new Category{Id = 3,Name = "Fruit"}
                                            };
            List<Product> products = new List<Product>
                                         {
                                             new Product{ProductId = 201,ProductName = "Chuckit",CategoryId = 2},
                                             new Product{ProductId = 202,ProductName = "SafeMade",CategoryId = 2},
                                             new Product{ProductId = 101,ProductName = "Taste",CategoryId = 1},
                                             new Product{ProductId = 102,ProductName = "Canidae",CategoryId = 1},
                                             new Product{ProductId = 103,ProductName = "Flavor",CategoryId = 1}

                                         };

            var productList = from category in categories
                              join product in products on category.Id equals product.CategoryId
                              into categoryProducts
                              select new { category.Name, Products= categoryProducts };

            foreach (var product in productList)
            {
                foreach (var item in product.Products)
                {
                    Console.WriteLine("{0}----{1}", product.Name, item.ProductName);    
                }
            }

 

 

重点关注一下查询表达式和执行操作,

从执行的第二个foreach操作,我们可以看出,into后面的categoryProducts事实上市join子句返回回来的Product对象的序列。

我们还可以将上述例子改成:

 

var productList = from category in categories
                  join product in products on category.Id equals product.CategoryId
                  into categoryProducts
                  from product1 in categoryProducts 
                  select new { category.Name, product1.ProductName };

            foreach (var product in productList)
            {
                Console.WriteLine("{0}----{1}", product.Name, product.ProductName);    
            }

 

 

3)左外部联接

左外部联接类似于left join,即左边的数据源不管有没有找到右边数据源的匹配项,都会全部输出来。

在左外部联接中,我们需要用到DefaultIfEmpty关键字,用来指定,当右边的数据源没有匹配想的时候,如何定义右边数据源的返回值,

还是以上面的例子为例:

 

var productList = from category in categories
                  join product in products on category.Id equals product.CategoryId
                  into categoryProducts
                  from item in categoryProducts.DefaultIfEmpty(new Product{ProductId = 0,ProductName = string.Empty,CategoryId = 0})
                  select new { category.Name, item.ProductName };

 

 

在这个例子中,如果category没有找到匹配的product,则product默认返回ProductId=0,CategoryId=0,ProductName=””这样对象。

 

 

To Be Continue…

 

参考:webcast《跟我一起学Visual Studio 2008系列课程》

posted @ 2012-03-15 16:06  Xiao Tian  阅读(591)  评论(0编辑  收藏  举报