EF 中多对多联接的最佳做法

本文关键字:最佳 EF | 更新日期: 2023-09-27 18:30:46

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

使用这些表格

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

CustomerOrder 表未添加到 edmx 中,因此这些表无法与常规(常规意味着我们过去在 LINQ to 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 子句中指定条件来执行多项选择和"连接",或使用相交关键字。但我想知道在这种情况下,最佳做法是什么。

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

EF 中多对多联接的最佳做法

为了澄清起见,添加两个表时,连接表不是 edmx 的一部分,除非它包含的不仅仅是连接表 ID。 在 EF 决定不使用联接表作为实体的情况下,其他每个表都应具有导航属性(Orders具有ICollection<Customer> CustomersCustomers具有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]