繁体   English   中英

EF 中多对多联接的最佳实践

[英]Best practice for many-to-many joins in EF

实体框架中多对多连接的最佳解决方案是什么。 在将表添加到 edmx 文件后我们使用 EF 的一个项目中,它似乎忽略了添加交集实体,即:

有了这些表

Customer(CustomerId,...)
CustomerOrder(CustomerId,OrderId)
Order(OrderId,...)

CustomerOrder 表未添加到 edmx,因此无法使用传统的(传统的意思是我们过去在 LINQ 中对 SQL 的做法)内部连接查询连接这些表,例如

var q = from c in db.Customers
        join co in db.CustomerOrders on c.CustomerId equals co.CustomerId
        join o in db.Orders on co.OrderId equals o.OrderId
        select a;

正如我通过查看之前提出的问题了解到的那样,您可以通过在 where 子句中指定条件或使用 intersects 关键字来进行多项选择和“加入”。 但我想知道这种情况下的最佳做法是什么。

假设我想找出客户有哪些订单,我将如何编写该查询 go。

只是为了澄清,当添加两个表时,连接表不是 edmx 的一部分,除非它包含的不仅仅是连接表 ID。 在 EF决定不将连接表用作实体的情况下,其他每个表都应具有导航属性( Orders将具有ICollection<Customer> Customers ,而Customers将具有ICollection<Orders> )以允许访问连接表无需手动加入他们。 在那种情况下,您将能够执行以下操作:

var customer = dbContext.Customers.Include("Orders")
                                  .Where(o => o.Orders.OrderID == 2);

通常,导航属性是延迟加载的,其中对象不在实体的属性中,直到它们被代码访问。 如果您知道要使用它们,则可以手动告诉框架立即加载它们,方法是使用Include方法。 此示例中的此方法不是访问Orders.OrderID值所必需的。

对于有类似问题的任何人的未来参考,我只需要查看 EF 实际生成的内容,显然 EF 足够聪明,可以在隐藏相交实体时在必要时添加连接,例如:

var query = from c in db.Clients
from o in db.Orders
where c.Id == 1 
select o.Id;

生成以下 sql:

SELECT
[Extent2].[Id] AS [Id]
FROM  [dbo].[Client] AS [Extent1]
CROSS JOIN [dbo].[Order] AS [Extent2]
WHERE 1 = [Extent1].[Id]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM