join 子句可用于将来自不同源序列并且在对象模型中没有直接关系的元素相关联。 唯一的要求是每个源中的元素需要共享某个可以进行比较以判断是否相等的值。 例如,食品经销商可能拥有某种产品的供应商列表以及买主列表。 例如,可以使用 join 子句创建该产品同一指定地区供应商和买主的列表。

join 子句将 2 个源序列作为输入。 每个序列中的元素都必须是可以与其他序列中的相应属性进行比较的属性,或者包含一个这样的属性。 join 子句使用特殊 equals 关键字比较指定的键是否相等。 join 子句执行的所有联接都是同等联接。 join 子句的输出形式取决于执行的联接的具体类型。 以下是 3 种最常见的联接类型:

  • 内部联接

  • 分组联接

  • 左外部联接

内部联接

以下示例演示了一个简单的内部同等联接。 此查询生成一个“产品名称/类别”对平面序列。 同一类别字符串将出现在多个元素中。 如果 categories 中的某个元素不具有匹配的 products,则该类别不会出现在结果中。

var innerJoinQuery =
from category in categories
join prod in products on category.ID equals prod.CategoryID
select new { ProductName = prod.Name, Category = category.Name }; //produces flat sequence

Group Join

含有 into 表达式的 join 子句称为分组联接。

var innerGroupJoinQuery =
from category in categories
join prod in products on category.ID equals prod.CategoryID into prodGroup
select new { CategoryName = category.Name, Products = prodGroup };

分组联接会生成分层的结果序列,该序列将左侧源序列中的元素与右侧源序列中的一个或多个匹配元素相关联。 分组联接没有等效的关系术语;它本质上是一个对象数组序列。

如果在右侧源序列中找不到与左侧源中的元素相匹配的元素,则 join 子句会为该项生成一个空数组。 因此,分组联接基本上仍然是一种内部同等联接,区别在于分组联接将结果序列组织为多个组。

如果只选择分组联接的结果,则可访问各项,但无法识别结果所匹配的项。 因此,通常更为有用的做法是:选择分组联接的结果并将其放入一个也包含该项名的新类型中,如上例所示。

当然,还可以将分组联接的结果用作其他子查询的生成器:

var innerGroupJoinQuery2 =
from category in categories
join prod in products on category.ID equals prod.CategoryID into prodGroup
from prod2 in prodGroup
where prod2.UnitPrice > 2.50M
select prod2;

左外部联接

在左外部联接中,将返回左侧源序列中的所有元素,即使右侧序列中没有其匹配元素也是如此。 若要在 LINQ 中执行左外部联接,请结合使用 DefaultIfEmpty 方法与分组联接,指定要在某个左侧元素不具有匹配元素时生成的默认右侧元素。 可以使用 null 作为任何引用类型的默认值,也可以指定用户定义的默认类型。 以下示例演示了用户定义的默认类型:

var leftOuterJoinQuery =
from category in categories
join prod in products on category.ID equals prod.CategoryID into prodGroup
from item in prodGroup.DefaultIfEmpty(new Product { Name = String.Empty, CategoryID = })
select new { CatName = category.Name, ProdName = item.Name };

组合键

可通过使用组合键测试多个值是否相等。 有关详细信息,请参阅如何:使用组合键进行联接。 还可以在 group 子句中使用组合键。

var query = from o in db.Orders
from p in db.Products
join d in db.OrderDetails
on new {o.OrderID, p.ProductID} equals new {d.OrderID,d.ProductID} into details
from d in details
select new {o.OrderID, p.ProductID, d.UnitPrice};

if the Orders table and OrderDetails table each used different names for their columns, you could create composite keys by assigning identical names in the anonymous types:

join...on new {Name = o.CustomerName, ID = o.CustID} equals
new {Name = d.CustName, ID = d.CustID }

最新文章

  1. BW常用事务码Tcode
  2. Elasticsearch refresh vs. flush【转载】
  3. 搭建Java环境JDK,和运行环境JRE
  4. APNS IOS PHP 苹果推送
  5. 简单的C语言小学四则运算设计
  6. 设计模式之Inheritance versus Parameterized Types 继承和参数化类型
  7. CMD/AMD
  8. aix 文件大小相关查询
  9. 简单的留言板(dom+正则练习)
  10. 4)C语言指针(C自考学习)
  11. Python 3 利用 Dlib 19.7 实现人脸识别和剪切
  12. Centos7中文乱码问题的解决
  13. Scaffold-DbContext 命令参数
  14. Yara VS2017出现LINK : fatal error LNK1104: 无法打开文件“msvcrt.lib”
  15. GDOI2018 涛涛摘苹果 [CDQ分治]
  16. Windows 10 家庭版/专业版 彻底关闭windows update自动更新
  17. win 10 kms 激活 后 火狐 上 https 网站 报错
  18. Spring源码-循环依赖源码解读
  19. anaconda的源配置的坑
  20. bzoj千题计划290:bzoj3143: [Hnoi2013]游走

热门文章

  1. IDEA用maven创建springMVC项目和配置
  2. 关于C++中char 型变量的地址输出
  3. Java并发/多线程系列——线程安全篇(1)
  4. SGU180(树状数组,逆序对,离散)
  5. NOIP2017SummerTraining0726
  6. Asp.net中防止用户多次登录的方法
  7. vue脚手架使用swiper /引入js文件/引入css文件
  8. ZOJ1171
  9. c#中list使用示例
  10. 【记录一次windows技术学习】使用笔记本DOS命令搭建WLAN热点