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

时间:2012-04-11 05:34:19

标签: c# entity-framework-4 many-to-many

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

使用这些表格

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子句中指定条件来进行多次选择和“连接”,或使用intersects关键字。但我想知道这类情况的最佳做法是什么。

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

2 个答案:

答案 0 :(得分:5)

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

ICollection<Orders>

通常,导航属性是延迟加载的,其中对象在代码访问之前不在实体的属性中。如果您知道要使用Include方法使用它们,可以手动告诉框架立即加载它们。此示例中的此方法不是必需的,以便访问var customer = dbContext.Customers.Include("Orders") .Where(o => o.Orders.OrderID == 2); 值。

答案 1 :(得分:0)

对于具有类似问题的任何人的未来参考,我只需要看看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]