2010-07-26 418 views
0

我的LINQ查詢包含下列集團By語句:優化LINQ到SQL查詢,集團通過多個領域的

Group p By Key = New With { _ 
.Latitude = p.Address.GeoLocations.FirstOrDefault(Function(g) New String() {"ADDRESS", "POINT"}.Contains(g.Granularity)).Latitude, _ 
.Longitude = p.Address.GeoLocations.FirstOrDefault(Function(g) New String() {"ADDRESS", "POINT"}.Contains(g.Granularity)).Longitude} 

查詢工作,但這裏要說的是上面的條款產生

SELECT [t6].[Latitude] 
      FROM (
       SELECT TOP (1) [t5].[Latitude] 
       FROM [dbo].[GeoLocations] AS [t5] 
       WHERE ([t5].[Granularity] IN (@p0, @p1)) AND ([t5].[AddressId] = [t2].[Addr_AddressId]) 
       ) AS [t6] 
      ) AS [value], (
      SELECT [t8].[Longitude] 
      FROM (
       SELECT TOP (1) [t7].[Longitude] 
       FROM [dbo].[GeoLocations] AS [t7] 
       WHERE ([t7].[Granularity] IN (@p2, @p3)) AND ([t7].[AddressId] = [t2].[Addr_AddressId]) 
       ) AS [t8] 
      ) AS [value2] 
的SQL

我不是SQL專家,但它在我看來這是相當不理想的翻譯。這實際上應該是一個查詢,從第一條記錄中選擇經緯度。也許SQL Server Optimizer會照顧到這一點。但是有什麼辦法可以推動Linq生成一個精簡的SQL語句?

我嘗試以下,太..

Group p By Key = p.Address.GeoLocations.Where(Function(g) New String() {"ADDRESS", "POINT"}.Contains(g.Granularity)). _ 
Select(Function(g) New With {.Latitude = g.Latitude, .Longitude = g.Longitude}).FirstOrDefault 

但這產生的誤差:「由表達A組只能包含可由所述服務器可比非恆定的標量」

回答

1

對不起在C#回覆...

這裏是你有什麼,翻譯成C#:

List<string> params = new List<string>() 
{ "Address", "Point" }; 

from p in people 
group p by new { 
    Latitude = p.Address.GeoLocations 
    .FirstOrDefault(g => params.Contains(g.Granularity)).Latitude, 
    Longitude = p.Address.GeoLocations 
    .FirstOrDefault(g => params.Contains(g.Granularity)).Longitude 
}; 

這裏有一個重寫,使用let關鍵字。

from p in people 
let loc = p.Address.GeoLocations 
    .FirstOrDefault(g => params.Contains(g.Granularity)) 
group p by new 
{ 
    Latitude = loc.Latitude, 
    Longitude = loc.Longitude 
}; 
+0

感謝您的建議。我之前沒有使用過關鍵字。這當然比我更優雅。但令人驚訝的是,生成的SQL是相同的。我在這一點上猜測,這只是Linq to SQL總是處理多個組鍵的方式。 – Antony 2010-07-26 21:28:38