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 = },
new Employee { FirstName = "Charlotte", LastName = "Weiss", EmployeeID = },
new Employee { FirstName = "Magnus", LastName = "Hedland", EmployeeID = },
new Employee { FirstName = "Vernette", LastName = "Price", EmployeeID = } }; // Create a list of students.
List<Student> students = new List<Student> {
new Student { FirstName = "Vernette", LastName = "Price", StudentID = },
new Student { FirstName = "Terry", LastName = "Earls", StudentID = },
new Student { FirstName = "Terry", LastName = "Adams", StudentID = } }; // 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(, ) }
equals new { dog.Owner, Letter = dog.Name.Substring(, ) }
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("\nThe 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
LINQ-内部联接的更多相关文章
- 深入剖析linq的联接
内联接 代码如下 from a in new List<string[]>{ ]{"张三","男"}, ]{"李四"," ...
- LINQ查询表达式(4) - LINQ Join联接
内部联接 按照关系数据库的说法,“内部联接”产生一个结果集,对于该结果集内第一个集合中的每个元素,只要在第二个集合中存在一个匹配元素,该元素就会出现一次. 如果第一个集合中的某个元素没有匹配元素,则它 ...
- SQL Server-交叉联接、内部联接基础回顾(十二)
前言 本节开始我们进入联接学习,关于连接这一块涉及的内容比较多,我们一步一步循序渐进学习,简短内容,深入的理解,Always to review the basics. 交叉联接(CROSS JOIN ...
- .NET LINQ 联接运算
联接运算 将两个数据源“联接”就是将一个数据源中的对象与另一个数据源中共享某个通用特性的对象关联起来. 当查询所面向的数据源相互之间具有无法直接领会的关系时,联接就成为一项重要的运 ...
- LINQ系列:Linq to Object联接操作符
联接是指将一个数据源对象与另一个数据源对象进行关联或联合的操作.这两个数据源对象通过一个共同的值或属性进行关联. LINQ的联接操作符将包含可匹配(或相同)关键字的两个或多个数据源中的值进行匹配. L ...
- [C#] 进阶 - LINQ 标准查询操作概述
LINQ 标准查询操作概述 序 “标准查询运算符”是组成语言集成查询 (LINQ) 模式的方法.大多数这些方法都在序列上运行,其中的序列是一个对象,其类型实现了IEnumerable<T> ...
- Linq查询基本操作
摘要:本文介绍Linq查询基本操作(查询关键字) - from 子句 - where 子句 - select子句 - group 子句 - into 子句 - orderby 子句 - join 子句 ...
- Linq查询表达式
目录 1. 概述 2. from子句 3. where子句 4. select子句 5. group子句 6. into子句 7. 排序子句 8. let子句 9. join子句 10. 小结 1. ...
- [读书笔记]C#学习笔记六: C#3.0Lambda表达式及Linq解析
前言 最早使用到Lambda表达式是因为一个需求:如果一个数组是:int[] s = new int[]{1,3,5,9,14,16,22};例如只想要这个数组中小于15的元素然后重新组装成一个数组或 ...
- linq之join子句
前面我们总结Linq查询子句总共有8个,join子句是我们讲解的最后一个子句.join子句也是相对比较复杂的,所以最后来讲.join子句可以处理两个数据源之间的联系,当然这两个数据源之间必须存在相关联 ...
随机推荐
- Kettle-Spoon入门示例
Spoon 是Kettle的设计调试工具 [Demo文档下载] https://files.cnblogs.com/files/shexunyu/Kettle-Spoon-Demo%E5%B8%AE% ...
- 一起来学Spring Cloud | 第三章:服务消费者 (负载均衡Ribbon)
一.负载均衡的简介: 负载均衡是高可用架构的一个关键组件,主要用来提高性能和可用性,通过负载均衡将流量分发到多个服务器,多服务器能够消除单个服务器的故障,减轻单个服务器的访问压力. 1.服务端负载均衡 ...
- STL使用迭代器逆向删除
网上有很多这种例子: void erase(vector<int> &v) { for(vector<int>::reverse_iterator ri=v.rbegi ...
- 事件冒泡之cancelBubble和stoppropagation的区别
事实上stoppropagation和cancelBubble的作用是一样的,都是用来阻止浏览器默认的事件冒泡行为. 不同之处在于stoppropagation属于W3C标准,试用于Firefox等浏 ...
- Django数据库创建与查询及ORM的概念
ORM:是封装在pymysql上层的文件.他的作用是把python语句转换成sql语句,从而去数据库里操作数据.从数据库里获得的数据,经过orm转换为对象,对象可以直接调用属性获得值.orm本质是个中 ...
- hihocoder1821 取卡片游戏
思路: 博弈dp. 实现: #include <iostream> #include <algorithm> #include <cstring> using na ...
- c语言中的->代表什么意思
c语言中 ->符号是什么意思? 比如c=a->b a为结构体或联合体的指针,->表示调用其成员
- InitialContext与lookup
Context initial = new InitialContext(); Object objref = initial.lookup("java:comp/env/ejb/Simpl ...
- 洛谷 2543 [AHOI2004]奇怪的字符串
题目描述 输入输出格式 输入格式: 输入文件中包含两个字符串X和Y.当中两字符串非0即1.序列长度均小于9999. 输出格式: X和Y的最长公共子序列长度. 输入输出样例 输入样例#1: 010101 ...
- (十二)mybatis之动态代理
mybatis之动态代理的应用 在前文(https://www.cnblogs.com/NYfor2018/p/9093472.html)我们知道了,Mybatis的使用需要用到Mapper映射文件, ...