按照关系数据库的说法,“内部联接”产生一个结果集,对于该结果集内第一个集合中的每一个元素,只要在第二个集合中存在一个匹配元素,该元素就会出现一次。 若是第一个集合中的某个元素没有匹配元素,则它不会出如今结果集内。 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