2012-02-02 68 views
4

我有一个查询,按顺序搜索所有住宿,按天排序。当我检查的服务器执行什么查询,我看向同一个表的多个连接在同一个按键如何编写linq查询以防止重复连接?

var parcourt = this.DataService.From<OrderItem>() 
           .Where(i => i.OrderId == orderId && i.Product.ProductTypeId == (int)ProductTypes.Accommodation) 
           .OrderBy(i => i.DayNumber) 
           .ThenBy(i => i.OrderItemId) 
           .Select(i => new 
           { 
            i.OrderItemId, 
            i.DayNumber, 
            i.Product.Establishment.Address, 
            i.Product.Establishment.Coordinates 
           }); 

如果(通过ToTraceString作为显示)检查所生成的SQL,你可以看到两个连接上ProductsEstablishments表。

SELECT 
[Project1].[OrderItemId] AS [OrderItemId], 
[Project1].[DayNumber] AS [DayNumber], 
[Project1].[Address] AS [Address], 
[Project1].[EstablishmentId] AS [EstablishmentId], 
[Project1].[Latitude] AS [Latitude], 
[Project1].[Longitude] AS [Longitude] 
FROM (SELECT 
    [Extent1].[OrderItemId] AS [OrderItemId], 
    [Extent1].[DayNumber] AS [DayNumber], 
    [Extent4].[Address] AS [Address], 
    [Extent5].[EstablishmentId] AS [EstablishmentId], 
    [Extent5].[Latitude] AS [Latitude], 
    [Extent5].[Longitude] AS [Longitude] 
    FROM  [dbo].[OrderItems] AS [Extent1] 
    INNER JOIN [dbo].[Products] AS [Extent2] ON [Extent1].[ProductId] = [Extent2].[ProductId] 
    LEFT OUTER JOIN [dbo].[Products] AS [Extent3] ON [Extent1].[ProductId] = [Extent3].[ProductId] 
    LEFT OUTER JOIN [dbo].[Establishments] AS [Extent4] ON [Extent3].[EstablishmentId] = [Extent4].[EstablishmentId] 
    LEFT OUTER JOIN [dbo].[Establishments] AS [Extent5] ON [Extent3].[EstablishmentId] = [Extent5].[EstablishmentId] 
    WHERE (1 = [Extent2].[ProductTypeId]) AND ([Extent1].[OrderId] = @p__linq__0) 
) AS [Project1] 
ORDER BY [Project1].[DayNumber] ASC, [Project1].[OrderItemId] ASC 

我怎样才能防止这种LINQ到实体,从上表中加入了两次?我如何重写查询以避免这种情况?

表结构变为如下(简化):

Table schema

这是查询

回答

3

你能尝试此查询?我想如果你明确地调用所有的连接,它不会自动创建连接。

var parcourt = (from i in this.DataService.OrderItem 
       join p in this.DataService.Product on p.ProductId equals i.ProductId 
       join e in this.DataService.Establishments on e.EstablishmentId equals p.EstablishmentId 
       where i.OrderId == orderId && p.ProductTypeId == (int)ProductTypes.Accomodation 
       orderby i.DayNumber, i.OrderItemId 
       select new 
       { 
        i.OrderItemId, 
        i.DayNumber, 
        e.Address, 
        e.Coordinates 
       }); 
+0

尽管它为'OrderItems'和'Products'之间的连接生成一个子查询,这实际上不再生成两个连接。但这可能只是Linq对实体的工作方式,所以我不会再打扰了。 – 2012-02-02 16:39:39

+0

使用您的查询将Sql Server中的执行时间缩短了大约70%(如执行计划所示)。谢谢。 – 2012-02-02 16:53:41