LINQ查詢表達式(4) - LINQ Join聯接

內部聯接

  按照關係數據庫的說法,「內部聯接」產生一個結果集,對於該結果集內第一個集合中的每一個元素,只要在第二個集合中存在一個匹配元素,該元素就會出現一次。 若是第一個集合中的某個元素沒有匹配元素,則它不會出如今結果集內。 Join 方法(經過 C# 中的 join 子句調用)可實現內聯。數據庫

  內部鏈接的4種變體:函數

  • 簡單聯接,它基於一個簡單的鍵未來自兩個數據源的元素相互關聯。
  • 複合聯接,它基於一個複合鍵未來自兩個數據源的元素相互關聯。 使用複合鍵(即由多個值組成的鍵)能夠基於多個屬性將元素相互關聯。
  • 多聯接,在其中連續的聯接操做被相互拼接在一塊兒。
  • 分組聯接

  下面分別描述:ui

  1. 內部聯接:簡單鍵聯接
         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() { // 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 };
         }
  2. 內部聯接:複合聯接
      與僅僅基於一個屬性將元素相互關聯不一樣,使用複合鍵可基於多個屬性來比較元素。 爲此,須要爲每一個集合指定鍵選擇器函數,以便返回一個由要比較的屬性組成的匿名類型。 若是給屬性加上了標籤,則這些屬性必須在每一個鍵的匿名類型中都有相同的標籤, 並且還必須以相同順序出現。
    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; }
            }
    
     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;
  3. 內部鏈接:多聯接
        能夠將任意數量的聯接操做拼接在一塊兒以執行多聯接。 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
            { }
    
                // 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 };

     

  4. 內部鏈接:分組聯接實現內部聯接
         在 query1 中,Person 對象列表基於與 Pet.Owner 屬性匹配的 Person 分組聯接到 Pet 對象列表。 分組聯接建立了一箇中間組集合,該集合中的每一個組都由一個 Person 對象和匹配的 Pet 對象序列組成。
            class Person
            {
                public string FirstName { get; set; }
                public string LastName { get; set; }
            }
    
            class Pet
            {
                public string Name { get; set; }
                public Person Owner { get; set; }
            }
    
            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 };

    分組聯接示例:執行分組聯接以建立 XML 的示例spa

    分組聯接很是適合於使用 LINQ to XML 來建立 XML。 本例結果選擇器函數建立表示已聯接對象的 XML 元素,而不是建立匿名類型。code

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

      XElement ownersAndPets = new XElement("PetOwners",
                from person in people
                join pet in pets on person equals pet.Owner into gj
                select new XElement("Person",
                    new XAttribute("FirstName", person.FirstName),
                    new XAttribute("LastName", person.LastName),
                    from subpet in gj
                    select new XElement("Pet", subpet.Name)));  

外部鏈接

  • 外部聯接(左外部聯接)

     左外部聯接是這樣一個聯接:在其中返回第一個集合的每一個元素,而不管該元素在第二個集合中是否具備相關元素。 可使用 LINQ 執行左經過對分組聯接的結果調用方法 DefaultIfEmpty<TSource> 外部聯接鏈接。對象

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

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

         // 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) };
  •  交差聯接
       var crossJoinQuery =
                        from c in categories
                        from p in products
                        select new { c.ID, p.Name };
  • 自定義的聯接操做
           var nonEquijoinQuery =
                        from p in products
                        let catIds = from c in categories
                                     select c.ID
                        where catIds.Contains(p.CategoryID) == true
                        select new { Product = p.Name, CategoryID = p.CategoryID };

參考

  [1] MSDN,執行內部鏈接blog

  [2] MSDN,執行分組鏈接element

相關文章
相關標籤/搜索