2010-07-26 180 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