• LINQ-内部联接


    一、简单键联接

    下面的示例创建两个集合,其中包含两种用户定义类型 Person 和 Pet 的对象。 查询使用 C# 中的 join 子句将 Person 对象与 Owner 是该 Person 的 Pet 对象匹配。 C# 中的 select 子句定义结果对象的外观。 在此示例中,结果对象是由所有者名字和宠物姓名组成的匿名类型。

    class Person
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
    }
    
    class Pet
    {
        public string Name { get; set; }
        public Person Owner { get; set; }
    }
    
    /// <summary>
    /// Simple inner join.
    /// </summary>
    public static void InnerJoinExample()
    {
        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" };
        Person rui = new Person { FirstName = "Rui", LastName = "Raposo" };
    
        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 = rui };
        Pet daisy = new Pet { Name = "Daisy", Owner = magnus };
    
        // Create two lists.
        List<Person> people = new List<Person> { magnus, terry, charlotte, arlene, rui };
        List<Pet> pets = new List<Pet> { barley, boots, whiskers, bluemoon, daisy };
    
        // Create a collection of person-pet pairs. Each element in the collection
        // is an anonymous type containing both the person's name and their pet's name.
        var query = from person in people
                    join pet in pets on person equals pet.Owner
                    select new { OwnerName = person.FirstName, PetName = pet.Name };
    
        foreach (var ownerAndPet in query)
        {
            Console.WriteLine($""{ownerAndPet.PetName}" is owned by {ownerAndPet.OwnerName}");
        }
    }
    
    // This code produces the following output:
    //
    // "Daisy" is owned by Magnus
    // "Barley" is owned by Terry
    // "Boots" is owned by Terry
    // "Whiskers" is owned by Charlotte
    // "Blue Moon" is owned by Rui

    请注意,LastName 是“Huff”的 Person 对象未出现在结果集中,因为没有 Pet 对象的 Pet.Owner 等于该 Person

    二、组合键联接

    可以使用复合键基于多个属性来比较元素,而不是只基于一个属性使元素相关联。 为此,请为每个集合指定键选择器函数,以返回由要比较的属性组成的匿名类型。 如果对属性进行标记,则它们必须在每个键的匿名类型中具有相同标签。 属性还必须按相同顺序出现。

    class Employee
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public int EmployeeID { get; set; }
    }
    
    class Student
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public int StudentID { get; set; }
    }
    
    /// <summary>
    /// Performs a join operation using a composite key.
    /// </summary>
    public static void CompositeKeyJoinExample()
    {
        // Create a list of employees.
        List<Employee> employees = new List<Employee> {
            new Employee { FirstName = "Terry", LastName = "Adams", EmployeeID = 522459 },
             new Employee { FirstName = "Charlotte", LastName = "Weiss", EmployeeID = 204467 },
             new Employee { FirstName = "Magnus", LastName = "Hedland", EmployeeID = 866200 },
             new Employee { FirstName = "Vernette", LastName = "Price", EmployeeID = 437139 } };
    
        // Create a list of students.
        List<Student> students = new List<Student> {
            new Student { FirstName = "Vernette", LastName = "Price", StudentID = 9562 },
            new Student { FirstName = "Terry", LastName = "Earls", StudentID = 9870 },
            new Student { FirstName = "Terry", LastName = "Adams", StudentID = 9913 } };
    
        // Join the two data sources based on a composite key consisting of first and last name,
        // to determine which employees are also students.
        IEnumerable<string> query = from employee in employees
                                    join student in students
                                    on new { employee.FirstName, employee.LastName }
                                    equals new { student.FirstName, student.LastName }
                                    select employee.FirstName + " " + employee.LastName;
    
        Console.WriteLine("The following people are both employees and students:");
        foreach (string name in query)
            Console.WriteLine(name);
    }
    
    // This code produces the following output:
    //
    // The following people are both employees and students:
    // Terry Adams
    // Vernette Price

    三、多联接

    可以将任意数量的联接操作相互追加,以执行多联接。 C# 中的每个 join 子句会将指定数据源与上一个联接的结果相关联。

    class Person
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
    }
    
    class Pet
    {
        public string Name { get; set; }
        public Person Owner { get; set; }
    }
    
    class Cat : Pet
    { }
    
    class Dog : Pet
    { }
    
    public static void MultipleJoinExample()
    {
        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" };
        Person rui = new Person { FirstName = "Rui", LastName = "Raposo" };
        Person phyllis = new Person { FirstName = "Phyllis", LastName = "Harris" };
    
        Cat barley = new Cat { Name = "Barley", Owner = terry };
        Cat boots = new Cat { Name = "Boots", Owner = terry };
        Cat whiskers = new Cat { Name = "Whiskers", Owner = charlotte };
        Cat bluemoon = new Cat { Name = "Blue Moon", Owner = rui };
        Cat daisy = new Cat { Name = "Daisy", Owner = magnus };
    
        Dog fourwheeldrive = new Dog { Name = "Four Wheel Drive", Owner = phyllis };
        Dog duke = new Dog { Name = "Duke", Owner = magnus };
        Dog denim = new Dog { Name = "Denim", Owner = terry };
        Dog wiley = new Dog { Name = "Wiley", Owner = charlotte };
        Dog snoopy = new Dog { Name = "Snoopy", Owner = rui };
        Dog snickers = new Dog { Name = "Snickers", Owner = arlene };
    
        // Create three lists.
        List<Person> people =
            new List<Person> { magnus, terry, charlotte, arlene, rui, phyllis };
        List<Cat> cats =
            new List<Cat> { barley, boots, whiskers, bluemoon, daisy };
        List<Dog> dogs =
            new List<Dog> { fourwheeldrive, duke, denim, wiley, snoopy, snickers };
    
        // The first join matches Person and Cat.Owner from the list of people and
        // cats, based on a common Person. The second join matches dogs whose names start
        // with the same letter as the cats that have the same owner.
        var query = from person in people
                    join cat in cats on person equals cat.Owner
                    join dog in dogs on 
                    new { Owner = person, Letter = cat.Name.Substring(0, 1) }
                    equals new { dog.Owner, Letter = dog.Name.Substring(0, 1) }
                    select new { CatName = cat.Name, DogName = dog.Name };
    
        foreach (var obj in query)
        {
            Console.WriteLine( 
                $"The cat "{obj.CatName}" shares a house, and the first letter of their name,
                with "{obj.DogName}".");  
        }
    }
    
    // This code produces the following output:
    //
    // The cat "Daisy" shares a house, and the first letter of their name, with "Duke".
    // The cat "Whiskers" shares a house, and the first letter of their name, with "Wiley".

     四、使用分组联接的内联

    下面的示例演示如何使用分组联接实现内部联接。

    query1 的结果等效于通过使用 join 子句(不使用 into 子句)执行内部联接来获取的结果集。 query2 变量演示了此等效查询。

    class Person
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
    }
    
    class Pet
    {
        public string Name { get; set; }
        public Person Owner { get; set; }
    }
    
    /// <summary>
    /// Performs an inner join by using GroupJoin().
    /// </summary>
    public static void InnerGroupJoinExample()
    {
        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 query1 = from person in people
                     join pet in pets on person equals pet.Owner into gj
                     from subpet in gj
                     select new { OwnerName = person.FirstName, PetName = subpet.Name };
    
        Console.WriteLine("Inner join using GroupJoin():");
        foreach (var v in query1)
        {
            Console.WriteLine($"{v.OwnerName} - {v.PetName}"));
        }
    
        var query2 = from person in people
                     join pet in pets on person equals pet.Owner
                     select new { OwnerName = person.FirstName, PetName = pet.Name };
            
        Console.WriteLine("
    The equivalent operation using Join():");
        foreach (var v in query2)
            Console.WriteLine($"{v.OwnerName} - {v.PetName}"));
    }
    
    // This code produces the following output:
    //
    // Inner join using GroupJoin():
    // Magnus - Daisy
    // Terry - Barley
    // Terry - Boots
    // Terry - Blue Moon
    // Charlotte - Whiskers
    //
    // The equivalent operation using Join():
    // Magnus - Daisy
    // Terry - Barley
    // Terry - Boots
    // Terry - Blue Moon
    // Charlotte - Whiskers

     

  • 相关阅读:
    通过PHP类的反射来实现依赖注入
    hyperf 基础篇
    composer install 遇到 lock 文件 warning
    laravel carbon 怎么计算两个时间的差?
    laravel 属性类型转换$casts
    Java Web安全之代码审计
    【代码审计】————2、aspx代码审计-2
    【代码审计】————1、aspx代码审计-1
    【逻辑漏洞技巧拓展】————9、业务逻辑漏洞探索之上传漏洞
    【逻辑漏洞技巧拓展】————8、业务逻辑漏洞探索之敏感信息泄露
  • 原文地址:https://www.cnblogs.com/wangyihome/p/10342091.html
Copyright © 2020-2023  润新知