我的LINQ查询包含以下Group By语句:
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}
查询有效,但这是上面生成的子句生成的SQL
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专家,但我认为这是一个相当不理想的翻译。这应该是一个从第一条记录中选择Latitide和Longitude的查询。也许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
但这会产生错误:“group by expression只能包含服务器可比较的非常量标量。”
答案 0 :(得分: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
};