使用EF
生成的sql语句是否存在任何性能问题C#代码:
public IQueryable<Lugar> NearestPOI(double lat, double lng, int> distance)
{
System.Data.Objects.ObjectResult<Int32?> AllowedPois = dbContext.SP_NearestPOI(lat, lng, 100000);
IQueryable<Lugar> POI = from c in dbContext.Lugars
where AllowedPois.Contains(c.id)
select c;
return POI;
}
EF4生成的查询:
SELECT
[Extent1].[id] AS [id],
[Extent1].[empresaId] AS [empresaId],
[Extent1].[usuarioId] AS [usuarioId],
[Extent1].[name] AS [name],
[Extent1].[description] AS [description],
[Extent1].[lat] AS [lat],
[Extent1].[lng] AS [lng],
[Extent1].[logoThumbnail] AS [logoThumbnail],
[Extent1].[imageType] AS [imageType]
FROM [dbo].[Lugares] AS [Extent1]
WHERE [Extent1].[id] IN (1,2,3,4,5,6,7)
我担心的是将AllowedPois查询作为一个单独的查询,在纯SQL语法上使用常规方法,如下所示:
SELECT * from dbo.Lugares L join dbo.NearestPOI(9.105306627167566,-79.38148587942118,100000) NL
on L.id = NL.id
由于我在这个项目中使用EF4,我想坚持使用它,并且不要使用字符串连接来查询。我尝试使用这种方法生成更引人注目的查询:
var POI = from c in dbContext.Lugars
join i in dbContext.SP_NearestPOI(lat, lng, 100000) on c.id equals i.Value
select c;
但是它给出了一个非常混乱的查询,其中包含N个联合,它们以allowedPois的数量递增:
SELECT
[Extent1].[id] AS [id],
[Extent1].[empresaId] AS [empresaId],
[Extent1].[usuarioId] AS [usuarioId],
[Extent1].[name] AS [name],
[Extent1].[description] AS [description],
[Extent1].[lat] AS [lat],
[Extent1].[lng] AS [lng],
[Extent1].[logoThumbnail] AS [logoThumbnail],
[Extent1].[imageType] AS [imageType]
FROM [dbo].[Lugares] AS [Extent1]
INNER JOIN (SELECT
[UnionAll5].[C1] AS [C1]
FROM (SELECT
[UnionAll4].[C1] AS [C1]
FROM (SELECT
[UnionAll3].[C1] AS [C1]
FROM (SELECT
[UnionAll2].[C1] AS [C1]
FROM (SELECT
[UnionAll1].[C1] AS [C1]
FROM (SELECT
1 AS [C1]
FROM ( SELECT 1 AS X ) AS [SingleRowTable1]
UNION ALL
SELECT
2 AS [C1]
FROM ( SELECT 1 AS X ) AS [SingleRowTable2]) AS [UnionAll1]
UNION ALL
SELECT
3 AS [C1]
FROM ( SELECT 1 AS X ) AS [SingleRowTable3]) AS [UnionAll2]
UNION ALL
SELECT
4 AS [C1]
FROM ( SELECT 1 AS X ) AS [SingleRowTable4]) AS [UnionAll3]
UNION ALL
SELECT
5 AS [C1]
FROM ( SELECT 1 AS X ) AS [SingleRowTable5]) AS [UnionAll4]
UNION ALL
SELECT
6 AS [C1]
FROM ( SELECT 1 AS X ) AS [SingleRowTable6]) AS [UnionAll5]
UNION ALL
SELECT
7 AS [C1]
FROM ( SELECT 1 AS X ) AS [SingleRowTable7]) AS [UnionAll6] ON [Extent1].[id] = [UnionAll6].[C1]
有关如何改进此操作的任何想法,还是应该使用对allowedPois的单独查询来坚持我的实际解决方案?
答案 0 :(得分:1)
你真的不应该在LINQ查询中使用连接语法。我的一部分希望他们没有在LINQ的C#语言中包含join运算符,因为它只会导致混乱,并且往往会产生这样的错误SQL。原因在于,当您想要执行where子句或在结果中包含该表时,您几乎总是加入SQL。 LINQ已经为此提供了很好的支持,但你只需要考虑LINQ方式而不是SQL方式。您的LINQ数据模型应该定义关系,因此您不需要通过连接重新定义它们。这里并不完全适用,因为您首先使用的是sproc,但适用相同的原则。您在C#中的第一个LINQ查询实际上是有效的方法。
所以,如果我不清楚的话。这是正确的代码。
public IQueryable<Lugar> NearestPOI(double lat, double lng, int> distance)
{
System.Data.Objects.ObjectResult<Int32?> AllowedPois = dbContext.SP_NearestPOI(lat, lng, 100000);
IQueryable<Lugar> POI = from c in dbContext.Lugars
where AllowedPois.Contains(c.id)
select c;
return POI;
}