4

在此处输入图像描述

首先使用 EF DB,我有两个具有多对多关系的实体(供应商、产品)。Entity Framework 不会为关联表 (SupplierProduct) 创建实体,因为关联表仅包含强实体的主键。

我通过以下查询获得了所有不提供给定产品的供应商:

var q1 = context.Suppliers.Where(s=>!s.Products.Any(p=>p.Id == 1));

生成的 SQL 使用与此类似的 EXISTS 相关子查询:

SELECT *
FROM Suppliers s
WHERE NOT EXISTS
  (SELECT 1 
   FROM SupplierProduct sp WHERE sp.SupplierId = s.Id && sp.ProductId = 1)

是否有可能使用 Linq to Entities 方法语法来生成在关联表上使用连接的查询?

IE:

SELECT DISTINCT s.*
FROM SupplierProduct sp
JOIN Supplier s ON s.Id = sp.SupplierId;
WHERE sp.ProductId != 1

更新

正如 JoeEnos 所指出的,我上面的查询并没有做同样的事情。NOT EXISTS 子查询可能是最好的方法。如果我试图找到所有提供产品的供应商怎么办?我会将我的 linq 更改为实体查询:

var q1 = context.Suppliers.Where(s => s.Products.Any(p=>p.Id == 1));

生成的 SQL 将是:

SELECT *
FROM Suppliers s
WHERE EXISTS
  (SELECT 1 
   FROM SupplierProduct sp WHERE sp.SupplierId = s.Id && sp.ProductId = 1)

这很好,我得到了我想要的结果。但是,如果我在这种情况下编写 SQL,我通常会这样做:

SELECT s.*
FROM SupplierProduct sp
JOIN Supplier s ON s.Id = sp.SupplierId;
WHERE sp.ProductId = 1

可以更改我的 linq to entity 查询以生成上述 SQL 吗?

4

2 回答 2

12

可以使用SelectMany()根据与另一个实体的 m:n 关联来选择实体时使用连接而不是 EXISTS 来生成 SQL 。例如:

var q1 = context.Suppliers.Where(s => s.Products.Any(p=>p.Id == 1));

可以改写为:

var q1 = context.Products.Where(p => p.Id == 1).SelectMany(p => p.Suppliers);
于 2013-02-26T10:09:03.247 回答
0

您的两个查询做了非常不同的事情。您的Any/EXISTS查询获取根本没有产品 1 的供应商。您的JOIN查询将获取拥有除 1 之外的任何其他产品的所有供应商,无论他们是否也拥有产品 1。

我认为你不能只用一个JOINand来做你要找的WHERE事情 - 你可以用一个IN子句来做,但我认为EXISTS查询是查找数据的最正确方法。

无论如何,Entity Framework 的一大优点是您不必担心会生成什么——只要 LINQ 语句没问题,它就会找到编写查询的最佳方式,而您应该永远不必看它。当您进行分页和其他类似的事情时尤其如此,其中 LINQ 很简单,但生成的 SQL 非常难看。

于 2013-02-26T06:31:38.907 回答