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

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

SelectMany

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

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

var q =
from c in db.Customers
from o in c.Orders
where c.City == "London"
select o;

语句描述:Customers与Orders是一对多关系。即Orders在Customers类中以EntitySet形式出现。

所以第二个from是从c.Orders而不是db.Orders里进行筛选。

这个例子在From子句中使用外键导航选择伦敦客户的所有订单

var q =
from p in db.Products
where p.Supplier.Country == "USA" && p.UnitsInStock ==
select p;

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

SELECT [t0].[ProductID], [t0].[ProductName], [t0].[SupplierID],
[t0].[CategoryID],[t0].[QuantityPerUnit],[t0].[UnitPrice],
[t0].[UnitsInStock], [t0].[UnitsOnOrder],[t0].[ReorderLevel],
[t0].[Discontinued] FROM [dbo].[Products] AS [t0]
LEFT OUTER JOIN [dbo].[Suppliers] AS [t1] ON
[t1].[SupplierID] = [t0].[SupplierID]
WHERE ([t1].[Country] = @p0) AND ([t0].[UnitsInStock] = @p1)
-- @p0: Input NVarChar (Size = 3; Prec = 0; Scale = 0) [USA]
-- @p1: Input Int (Size = 0; Prec = 0; Scale = 0) [0]

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

var q =
from e in db.Employees
from et in e.EmployeeTerritories
where e.City == "Seattle"
select new
{
e.FirstName,
e.LastName,
et.Territory.TerritoryDescription
};

说明:多对多关系一般会涉及三个表(如果有一个表是自关联的,那有可能只有2个表)。这一句语句涉及Employees, EmployeeTerritories, Territories三个表。它们的关系是1:M:1。Employees和Territories没有很明确的关系。

语句描述:这个例子在From子句中使用外键导航筛选在西雅图的雇员,同时列出其所在地区。这条生成SQL语句为:

SELECT [t0].[FirstName], [t0].[LastName], [t2].[TerritoryDescription]
FROM [dbo].[Employees] AS [t0] CROSS JOIN [dbo].[EmployeeTerritories]
AS [t1] INNER JOIN [dbo].[Territories] AS [t2] ON
[t2].[TerritoryID] = [t1].[TerritoryID]
WHERE ([t0].[City] = @p0) AND ([t1].[EmployeeID] = [t0].[EmployeeID])
-- @p0: Input NVarChar (Size = 7; Prec = 0; Scale = 0) [Seattle]

3.自联接关系:

var q =
from e1 in db.Employees
from e2 in e1.Employees
where e1.City == e2.City
select new {
FirstName1 = e1.FirstName, LastName1 = e1.LastName,
FirstName2 = e2.FirstName, LastName2 = e2.LastName,
e1.City
};

语句描述:这个例子在select 子句中使用外键导航筛选成对的雇员,每对中一个雇员隶属于另一个雇员,且两个雇员都来自相同城市。生成SQL语句为:

SELECT [t0].[FirstName] AS [FirstName1], [t0].[LastName] AS
[LastName1],[t1].[FirstName] AS [FirstName2], [t1].[LastName] AS
[LastName2],[t0].[City] FROM [dbo].[Employees] AS [t0],
[dbo].[Employees] AS [t1] WHERE ([t0].[City] = [t1].[City]) AND
([t1].[ReportsTo] = [t0].[EmployeeID])

GroupJoin

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

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

此示例显式联接两个表并从这两个表投影出结果:

var q =
from c in db.Customers
join o in db.Orders on c.CustomerID
equals o.CustomerID into orders
select new
{
c.ContactName,
OrderCount = orders.Count()
};

说明:在一对多关系中,左边是1,它每条记录为c(from c in db.Customers),右边是Many,其每条记录叫做o ( join o in db.Orders ),每对应左边的一个c,就会有一组o,那这一组o,就叫做orders,也就是说,我们把一组o命名为orders,这就是into用途。这也就是为什么在select语句中,orders可以调用聚合函数Count。在T-SQL中,使用其内嵌的T-SQL返回值作为字段值。如图所示:

生成SQL语句为:

SELECT [t0].[ContactName], (
SELECT COUNT(*)
FROM [dbo].[Orders] AS [t1]
WHERE [t0].[CustomerID] = [t1].[CustomerID]
) AS [OrderCount]
FROM [dbo].[Customers] AS [t0]

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

此示例显式联接三个表并分别从每个表投影出结果:

var q =
from c in db.Customers
join o in db.Orders on c.CustomerID
equals o.CustomerID into ords
join e in db.Employees on c.City
equals e.City into emps
select new
{
c.ContactName,
ords = ords.Count(),
emps = emps.Count()
};

生成SQL语句为:

SELECT [t0].[ContactName], (
SELECT COUNT(*)
FROM [dbo].[Orders] AS [t1]
WHERE [t0].[CustomerID] = [t1].[CustomerID]
) AS [ords], (
SELECT COUNT(*)
FROM [dbo].[Employees] AS [t2]
WHERE [t0].[City] = [t2].[City]
) AS [emps]
FROM [dbo].[Customers] AS [t0]

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

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

var q =
from e in db.Employees
join o in db.Orders on e equals o.Employee into ords
from o in ords.DefaultIfEmpty()
select new
{
e.FirstName,
e.LastName,
Order = o
};

说明:以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”表达式:

var q =
from c in db.Customers
join o in db.Orders on c.CustomerID
equals o.CustomerID into ords
let z = c.City + c.Country
from o in ords
select new
{
c.ContactName,
o.OrderID,
z
};

5.组合键(Composite Key):

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

var q =
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
};

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

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

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

var q =
from o in db.Orders
join e in db.Employees
on o.EmployeeID equals
(int?)e.EmployeeID into emps
from e in emps
select new
{
o.OrderID,
e.FirstName
};

LINQ to SQL语句(4)之Join的更多相关文章

  1. 年终巨献 史上最全 ——LINQ to SQL语句

    LINQ to SQL语句(1)之Where 适用场景:实现过滤,查询等功能. 说明:与SQL命令中的Where作用相似,都是起到范围限定也就是过滤作用的,而判断条件就是它后面所接的子句.Where操 ...

  2. LINQ to SQL语句非常详细(原文来自于网络)

    LINQ to SQL语句(1)之Where Where操作 适用场景:实现过滤,查询等功能. 说明:与SQL命令中的Where作用相似,都是起到范围限定也就是过滤作用的,而判断条件就是它后面所接的子 ...

  3. LINQ to SQL语句

    http://kb.cnblogs.com/page/42477/2/ 本系列文章导航 LINQ to SQL语句(1)之Where LINQ to SQL语句(2)之Select/Distinct ...

  4. LINQ to SQL语句对应SQL的实现

    LINQ to SQL语句(1)之Where LINQ to SQL语句(2)之Select/Distinct LINQ to SQL语句(3)之Count/Sum/Min/Max/Avg LINQ ...

  5. LINQ to SQL语句大全

    LINQ to SQL语句大全     LINQ to SQL语句(1)之Where 适用场景:实现过滤,查询等功能. 说明:与SQL命令中的Where作用相似,都是起到范围限定也就是过滤作用的,而判 ...

  6. 【转】LINQ to SQL语句(1)之Where

    Where操作 适用场景:实现过滤,查询等功能. 说明:与SQL命令中的Where作用相似,都是起到范围限定也就是过滤作用的,而判断条件就是它后面所接的子句. Where操作包括3种形式,分别为简单形 ...

  7. 史上最全 ——LINQ to SQL语句

    LINQ to SQL语句(1)之Where 适用场景:实现过滤,查询等功能. 说明:与SQL命令中的Where作用相似,都是起到范围限定也就是过滤作用的,而判断条件就是它后面所接的子句.Where操 ...

  8. LINQ to SQL语句(7)之Exists/In/Any/All/Contains

    适用场景:用于判断集合中元素,进一步缩小范围. Any 说明:用于判断集合中是否有元素满足某一条件:不延迟.(若条件为空,则集合只要不为空就返回True,否则为False).有2种形式,分别为简单形式 ...

  9. LINQ to SQL语句(9)之Top/Bottom和Paging和SqlMethods

    适用场景:适量的取出自己想要的数据,不是全部取出,这样性能有所加强. Take 说明:获取集合的前n个元素:延迟.即只返回限定数量的结果集. var q = ( from e in db.Employ ...

随机推荐

  1. note of introduction of Algorithms(Lecture 3 - Part1)

    Lecture 3(part 1) Divide and conquer 1. the general paradim of algrithm as bellow: 1. divide the pro ...

  2. Java框架介绍-13个不容错过的框架项目

    本文转自互联网,个人收藏所用. 下面,我们将一同分享各有趣且颇为实用的Java库,大家请任取所需.不用客气~ 1.极致精简的Java Bootique是一项用于构建无容器可运行Java应用的极简技术. ...

  3. netstat 1

    lsof -i   :8086 第二个参数需要:开头 netstat linux  -a (all)显示所有选项,默认不显示LISTEN相关 理解这个很关键, 这是为什么我们netstat -a 不显 ...

  4. 谨慎DateTime.Now在EF的query中的使用

    执行如下代码: var query = from tr in _carrierRepository select new BaseCarrier { CarrierCode = tr.CarrierC ...

  5. 使用SQLAlchemy

    使用SQLAlchemy 参考: http://www.sqlalchemy.org/ https://www.keakon.net/2012/12/03/SQLAlchemy%E4%BD%BF%E7 ...

  6. Python的枚举类型

    Python的 Python的没有我们有两种用法: 创建Enum的实例 创建Enum的subclass 创建Enum的实例 from enum import Enum, unique Month = ...

  7. Oracle SQL 优化原则(实用篇)

    由于SQL优化优化起来比较复杂,并且还受环境限制,在开发过程中,写SQL必须遵循以下几点原则: 1.Oracle 采用自下而上的顺序解析WHERE子句,根据这个原理,表之间的连接必须写在其他Where ...

  8. Hidden File For Mac

    显示所有隐藏文件的方法: terminal中输入: defaults write com.apple.finder AppleShowAllFiles -bool true 同理,再次隐藏就输入: d ...

  9. Parametric Curves and Surfaces

    Parametric Curves and Surfaces eryar@163.com Abstract. This paper is concerned with parametric curve ...

  10. Hadoop官方文档翻译——YARN Architecture(2.7.3)

    The fundamental idea of YARN is to split up the functionalities of resource management and job sched ...