Join操作符

适用场景:在我们表关系中有一对一关系,一对多关系,多对多关系等。对各个表之间的关系,就用这些实现对多个表的操作。

说明:在Join操作中,分别为Join(Join查询), SelectMany(Select一对多选择)和GroupJoin(分组Join查询)。 该扩展方法对两个序列中键匹配的元素进行inner join操作

SelectMany

说明:我们在写查询语句时,如果被翻译成SelectMany需要满足2个条件。1:查询语句中没有join和into,2:必须出现EntitySet。在我们表关系中有一对一关系,一对多关系,多对多关系等,下面分别介绍一下。

1.一对多关系(1 to Many):

  1. var q =
  2. from c in db.Customers
  3. from o in c.Orders
  4. where c.City == "London"
  5. select o;

语句描述:Customers与Orders是一对多关系。即Orders在Customers类中以EntitySet形式出现。所以第二个from是从c.Orders而不是db.Orders里进行筛选。这个例子在From子句中使用外键导航选择伦敦客户的所有订单。

  1. var q =
  2. from p in db.Products
  3. where p.Supplier.Country == "USA" && p.UnitsInStock == 0
  4. select p;

语句描述:这一句使用了p.Supplier.Country条件,间接关联了Supplier表。这个例子在Where子句中使用外键导航筛选其供应商在美国且缺货的产品。

2.多对多关系(Many to Many):

  1. var q =
  2. from e in db.Employees
  3. from et in e.EmployeeTerritories
  4. where e.City == "Seattle"
  5. select new
  6. {
  7. e.FirstName,
  8. e.LastName,
  9. et.Territory.TerritoryDescription
  10. };

3.自联接关系:

  1. var q =
  2. from e1 in db.Employees
  3. from e2 in e1.Employees
  4. where e1.City == e2.City
  5. select new {
  6. FirstName1 = e1.FirstName, LastName1 = e1.LastName,
  7. FirstName2 = e2.FirstName, LastName2 = e2.LastName,
  8. e1.City
  9. };

 GroupJoin

像上面所说的,没有join和into,被翻译成SelectMany,同时有join和into时,那么就被翻译为GroupJoin。在这里into的概念是对其结果进行重新命名。

1.双向联接(Two way join):

  1. var q =
  2. from c in db.Customers
  3. join o in db.Orders on c.CustomerID
  4. equals o.CustomerID into orders
  5. select new
  6. {
  7. c.ContactName,
  8. OrderCount = orders.Count()
  9. };

生成SQL语句为:

  1. SELECT [t0].[ContactName], (
  2. SELECT COUNT(*)
  3. FROM [dbo].[Orders] AS [t1]
  4. WHERE [t0].[CustomerID] = [t1].[CustomerID]
  5. ) AS [OrderCount]
  6. FROM [dbo].[Customers] AS [t0]

2.三向联接(There way join):

  1. var q =
  2. from c in db.Customers
  3. join o in db.Orders on c.CustomerID
  4. equals o.CustomerID into ords
  5. join e in db.Employees on c.City
  6. equals e.City into emps
  7. select new
  8. {
  9. c.ContactName,
  10. ords = ords.Count(),
  11. emps = emps.Count()
  12. };

生成SQL语句为:

  1. SELECT [t0].[ContactName], (
  2. SELECT COUNT(*)
  3. FROM [dbo].[Orders] AS [t1]
  4. WHERE [t0].[CustomerID] = [t1].[CustomerID]
  5. ) AS [ords], (
  6. SELECT COUNT(*)
  7. FROM [dbo].[Employees] AS [t2]
  8. WHERE [t0].[City] = [t2].[City]
  9. ) AS [emps]
  10. FROM [dbo].[Customers] AS [t0]

3.左外部联接(Left Outer Join):

此示例说明如何通过使用 此示例说明如何通过使用DefaultIfEmpty() 获取左外部联接。在雇员没有订单时,DefaultIfEmpty()方法返回null:

  1. var q =
  2. from e in db.Employees
  3. join o in db.Orders on e equals o.Employee into ords
  4. from o in ords.DefaultIfEmpty()
  5. select new
  6. {
  7. e.FirstName,
  8. e.LastName,
  9. Order = o
  10. };

说明:以Employees左表,Orders右表,Orders 表中为空时,用null值填充。Join的结果重命名ords,使用DefaultIfEmpty()函数对其再次查询。其最后的结果中有个Order,因为from o in ords.DefaultIfEmpty() 是对ords组再一次遍历,所以,最后结果中的Order并不是一个集合。但是,如果没有from o in ords.DefaultIfEmpty() 这句,最后的select语句写成select new { e.FirstName, e.LastName, Order = ords }的话,那么Order就是一个集合。

4.投影的Let赋值(Projected let assignment):

说明:let语句是重命名。let位于第一个from和select语句之间。

这个例子从联接投影出最终“Let”表达式:

  1. var q =
  2. from c in db.Customers
  3. join o in db.Orders on c.CustomerID
  4. equals o.CustomerID into ords
  5. let z = c.City + c.Country
  6. from o in ords
  7. select new
  8. {
  9. c.ContactName,
  10. o.OrderID,
  11. z
  12. };

 5.组合键(Composite Key):

这个例子显示带有组合键的联接:

  1. var q =
  2. from o in db.Orders
  3. from p in db.Products
  4. join d in db.OrderDetails
  5. on new
  6. {
  7. o.OrderID,
  8. p.ProductID
  9. } equals
  10. new
  11. {
  12. d.OrderID,
  13. d.ProductID
  14. }
  15. into details
  16. from d in details
  17. select new
  18. {
  19. o.OrderID,
  20. p.ProductID,
  21. d.UnitPrice
  22. };

说明:使用三个表,并且用匿名类来说明:使用三个表,并且用匿名类来表示它们之间的关系。它们之间的关系不能用一个键描述清楚,所以用匿名类,来表示组合键。还有一种是两个表之间是用组合键表示关系的,不需要使用匿名类。

6.可为null/不可为null的键关系(Nullable/Nonnullable Key Relationship):

这个实例显示如何构造一侧可为 null 而另一侧不可为 null 的联接:

  1. var q =
  2. from o in db.Orders
  3. join e in db.Employees
  4. on o.EmployeeID equals
  5. (int?)e.EmployeeID into emps
  6. from e in emps
  7. select new
  8. {
  9. o.OrderID,
  10. e.FirstName
  11. };

【转】Linq 语法的更多相关文章

  1. Linq语法详细

    闲言碎语 近期比较忙,但还是想写点什么,就分享一些基础的知识给大家看吧,希望能帮助一些linq新手,如果有其它疑问,可以进右上角群,进行交流探讨,谢谢. 开门见山 读这篇文章之前,我先说下,每一种搜索 ...

  2. Linq语法详细(转)

    原文地址:http://www.cnblogs.com/knowledgesea/p/3897665.html 开门见山 读这篇文章之前,我先说下,每一种搜索结果集,我都以三种方式变现出来,为啦更好的 ...

  3. Linq To Sql中实现Left Join与Inner Join使用Linq语法与lambda表达式

    当前有两个表,sgroup与sgroupuser,两者通过gKey关联,而sgroup表记录的是组,而sgroupuser记录是组中的用户,因此在sgroupuser中不一定有数据.需要使用Left ...

  4. Linq语法

    希望能帮助一些linq新手. 开门见山 读这篇文章之前,我先说下,每一种搜索结果集,我都以三种方式变现出来,为啦更好的理解,希望不要嫌我啰嗦. 1.简单的linq语法 //1 var ss = fro ...

  5. Lamda和Linq语法对比详细

    本人转载:http://www.cnblogs.com/knowledgesea/p/3897665.html 闲言碎语 近期比较忙,但还是想写点什么,就分享一些基础的知识给大家看吧,希望能帮助一些l ...

  6. Linq 语法举例

    1.简单的linq语法 //1 var ss = from r in db.Am_recProScheme select r; //2 var ss1 = db.Am_recProScheme; // ...

  7. LinQ 语法基础

    LINQ (Language-Integrated Query,语言集成查询). LINQ to Objects.LINQ to SQL.LINQ to DataSet和LINQ to XML,它们分 ...

  8. Linq语法常见普通语法

    闲言碎语 近期比较忙,但还是想写点什么,就分享一些基础的知识给大家看吧,希望能帮助一些linq新手,如果有其它疑问,可以进右上角群,进行交流探讨,谢谢. 开门见山 读这篇文章之前,我先说下,每一种搜索 ...

  9. C# LINQ语法详解

    1.简单的linq语法 var ss = from r in db.Am_recProScheme select r; var ss1 = db.Am_recProScheme; string sss ...

  10. LINQ语法类似于SQL的语法

    LINQ语法类似于SQL的语法如下, Models.BookStoreEntities 是从添加新建项中的数据--->ADO.NET实体数据模型--->从数据库生成--->使用5.0 ...

随机推荐

  1. numpy和matlab计算协方差矩阵的不同(matlab是标准的,numpy相当于转置后计算)

    matlab是标准的,numpy相当于转置后计算 >> x = [2,0,-1.4;2.2,0.2,-1.5;2.4,0.1,-1;1.9,0,-1.2] x = 2.0000    0 ...

  2. kvm 基础 虚拟机改名

    转自:http://www.cnblogs.com/5201351/p/4464350.htm 1.查看所有的kvm虚拟机 [root@5201351_kvm ~]# virsh list --all ...

  3. k8s 基础 问题

    vim /usr/lib/systemd/system/docker.service --insecure-registry registry.access.redhat.com \ ubelet.s ...

  4. MySql集合查询

    SELECT语句的查询结果是元组的集合,所以多个SELECT语句的结果可进行集合操作. 集合操作主要包括并操作UNION.交操作INTERSECT.差操作EXCEPT. 注意,参加集合操作的各查询结果 ...

  5. OpenCV 鼠标手动绘制掩码图像

    OpenCV 鼠标手动绘制掩码图像 完整的代码: #include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui ...

  6. 获取显示屏的个数和分辨率 --- 通过使用OpenGL的GLFW库

    获取显示屏的个数和分辨率 - 通过使用OpenGL的GLFW库 程序 #include <iostream> // GLFW #include <GLFW/glfw3.h> i ...

  7. hbase-0.98.1-cdh5.1.0伪分布式安装

    分三步: 1. 添加环境变量 2.编辑hbase-env.sh文件 3.编辑hbase-site.xml 文件 前提条件是安装好hadoop,下面展开说明 1. 添加环境变量 export HBASE ...

  8. 6 大主流 Web 框架优缺点对比:15篇前端热文回看

    摘自:http://blog.csdn.net/VhWfR2u02Q/article/details/78993079 注:以下文章,点击标题即可阅读 <6 大主流 Web 框架优缺点对比> ...

  9. Python最小二乘法解非线性超定方程组

    求解非线性超定方程组,网上搜到的大多是线性方程组的最小二乘解法,对于非线性方程组无济于事. 这里分享一种方法:SciPy库的scipy.optimize.leastsq函数. import numpy ...

  10. 深入学习JavaScript: apply 方法 详解

    我在一开始看到javascript的函数apply和call时,非常的模糊,看也看不懂,最近在网上看到一些文章对apply方法和call的一些示例,总算是看的有点眉目了,在这里我做如下笔记,希望和大家 ...