• Linq Coding Part Seven (Join之左外部联接、DefaultIfEmpty、GroupJoin)


    Join 子句有三种最常见的联接类型:内部联接分组联接,左外部联接
    本次介绍:左外部联接,DefaultIfEmpty, GroupJoin

        左外部联接:就是返回第一个集合的每个元素,而无论该元素在第二个集合中是否具有相关元素。可以使用 LINQ,通过对分组联接的

        结果调用 DefaultIfEmpty 来执行左外部联接。

    class Person
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
    }

    class Pet
    {
        public string Name { get; set; }
        public Person Owner { get; set; }
    }

    public void LeftOuterJoinExample()
    {
        Person magnus = new Person { FirstName = "Magnus", LastName = "Hedlund" };
        Person terry = new Person { FirstName = "Terry", LastName = "Adams" };
        Person charlotte = new Person { FirstName = "Charlotte", LastName = "Weiss" };
        Person arlene = new Person { FirstName = "Arlene", LastName = "Huff" };

     

        Pet barley = new Pet { Name = "Barley", Owner = terry };
        Pet boots = new Pet { Name = "Boots", Owner = terry };
        Pet whiskers = new Pet { Name = "Whiskers", Owner = charlotte };
        Pet bluemoon = new Pet { Name = "Blue Moon", Owner = terry };
        Pet daisy = new Pet { Name = "Daisy", Owner = magnus };

     

        // Create two lists.
        List<Person> people = new List<Person> { magnus, terry, charlotte, arlene };
        List<Pet> pets = new List<Pet> { barley, boots, whiskers, bluemoon, daisy };

     

        var query = from person in people
                         join pet in pets on person equals pet.Owner into gj
                         from subpet in gj.DefaultIfEmpty()
                         select new
    {

                         person.FirstName,

                         PetName = (subpet == null ? String.Empty : subpet.Name)

                         };
                          //此时subpet为引用类型,所以此时这里是需要进行null检查的。

        foreach (var v in query)
        {
            Console.WriteLine("{0,-15}{1}", v.FirstName + ":", v.PetName);
        }
    }

    DefaultIfEmpty:通过使用延迟执行实现。即时返回值为一个对象,该对象存储执行操作所需的所有信息。

    它有两个重载方法:1.返回指定序列的元素;如果序列为空,则返回单一实例集合中的类型参数的默认值。

                                   2.返回指定序列中的元素;如果序列为空,则返回单一实例集合中的指定值。

    public class DefaultIfEmpty
        {
            public void DefaultifEmpty()
    //第一种方法重载DEMO
            {
                List<Category> categorys = new List<Category> {
                    new Category{ Name="AAAA", ID=11 },
                    new Category{ Name="AAAA", ID=13 },
                    new Category{ Name="AAAA", ID=14 }
                };

                foreach (Category category in categorys.DefaultIfEmpty())
                {
                    Console.WriteLine(category.Name);
                }
            }

            public void EmptyList()
            {
                List<Int32> numbers = new List<Int32>();

                foreach (Int32 number in numbers.DefaultIfEmpty())
                {
                    Console.WriteLine(number);
                }
            }

            public void DefaultifEmpty2()//第二种重载DEMO
            {
                Category defcategory = new Category { Name = "AAAA", ID = 13 };

                List<Category> categorys = new List<Category> {
                    new Category{ Name="AAAA", ID=11 },
                    new Category{ Name="AAAA", ID=13 },
                    new Category{ Name="AAAA", ID=14 }
                };

                foreach (Category category in categorys.DefaultIfEmpty(defcategory))
                {
                    Console.WriteLine("Name:{0}", category.ID);
                }

                List<Category> categoryEmpty = new List<Category>();

                foreach (Category category in categoryEmpty.DefaultIfEmpty(defcategory))
                {
                    Console.WriteLine("Name:{0}", category.Name);
                }
            }

            /*
              11
              13
              14
             
              AAAA
             */

            //从以下的结果可以看出来,
           //如果 source 不为空,是返回List<Category>的数据;
           //如果 source 为空时,则为包含 defaultValue 的 IEnumerable<(Of <(T>)>)。

     }

    *DefaultIfEmpty()方法与 GroupJoin 方法组合使用,可用于生成左外部联接。

     

    GroupJoin:基于键相等对两个序列的元素进行关联并对结果进行分组
    GroupJoin同样也有两个重载方法
                 1.使用默认的相等比较器 Default 对键进行比较。
                 2.使用指定的 IEqualityComparer<(Of <(T>)>) 对键进行比较。

     *以下代码执行结果均相同(只是三种不同的写法)

    public class  GroupJoin    {
            public void groupJoin()
            {
                ///Lamda 写法
                var query =

                Database.people.GroupJoin(Database.pets,
                                        person => person,
                                        pet => pet.Owner,
                                        (person, petCollection) =>
                                        new
                                        {
                                          OwnerName = person.FirstName,
                                          Pets = petCollection.Select(pet => pet.Name)
                                        });

                foreach (var obj in query)
                {
                    Console.WriteLine("{0}:", obj.OwnerName);
                    foreach (String pet in obj.Pets)
                    {
                        Console.WriteLine(" {0}", pet);
                    }
                }

                ///结果等同于Lamda
                var queryForLinq2 =
    from p in Database.people
                                join pp in Database.pets
                                on p.FirstName equals pp.Owner.FirstName
                                into peoplePets
                                select new
                                {
                                  OwnerName = p.FirstName,
                                  Pets = peoplePets.Select(pp => pp.Name)
                                };

                ///Linq 写法
               var queryForLinq =
    from p in Database.people
                               select new
                               {
                                 OwnerName = p.FirstName,
                                 Pets = from pp in Database.pets
                                        where p.FirstName == pp.Owner.FirstName
                                        select pp
                               };
                
            }
        }

    LINQ Coding 目录

    1. Linq Coding -- Part One
    2. Linq Coding -- Part Two[标准查询运算符]
    3. Linq Coding -- Part Three [Let子句]
    4. Linq Coding -- Part Four[Concat应用]
    5. Linq Coding -- Part Five (Join之内部联接查询)
    6. Linq Coding -- Part Six (Join之分组联接)
    7. Linq Coding -- Part Seven (Join之左外部联接、DefaultIfEmpty、GroupJoin)
    8. Linq Coding -- Part Eight (Equals Topic)
  • 相关阅读:
    python set()、len()、type()、保留小数、EOFError
    代码学习与感悟
    你的代码的风格
    python 面向对象的类
    ubuntu 上下左右键变成ABCD
    python运算符
    python 数据类型详解
    python关键字
    python 设计及调试的一些小技巧
    python-list
  • 原文地址:https://www.cnblogs.com/RuiLei/p/1271758.html
Copyright © 2020-2023  润新知