按照關係數據庫的說法,「內部聯接」產生一個結果集,對於該結果集內第一個集合中的每一個元素,只要在第二個集合中存在一個匹配元素,該元素就會出現一次。 若是第一個集合中的某個元素沒有匹配元素,則它不會出如今結果集內。 Join 方法(經過 C# 中的 join 子句調用)可實現內聯。數據庫
內部鏈接的4種變體:函數
下面分別描述:ui
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 };
}
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;
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 };
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