2012-02-02 69 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