Is there any performance issue to be aware about using this sql statement generated by EF
C# code:
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 Generated query:
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)
My concern is about doing the AllowedPois query as a separate one instaed of using the regular approach on pure SQL syntax that would be something like:
SELECT * from dbo.Lugares L join dbo.NearestPOI(9.105306627167566,-79.38148587942118,100000) NL
on L.id = NL.id
As im using EF4 for this project I would like to stick with it and do not use string concatenation for the querys. I tried to generate a more compelling query using this approach:
var POI = from c in dbContext.Lugars
join i in dbContext.SP_NearestPOI(lat, lng, 100000) on c.id equals i.Value
select c;
But it give out a really messy query with N number of unions that increments with the number of 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]
Any idea on how to improve this operation or should I stick with my actual solution using the separate query for the allowedPois?
You really shouldn’t use the join syntax in a LINQ query. Part of me wishes they didn’t include the join operator in the C# language for LINQ because it just leads to confusion and tends to generate bad SQL like this. The reason being is that you almost are always joining in SQL to when you want to do a where clause or include that table in your results. LINQ already has great support for this but you just have to think in the LINQ way and not the SQL way. Your LINQ data model should have the relationships defined so you don’t then need to redefine them through joins. Doesn’t totally apply here since you’re using a sproc first but same principles apply. Your first LINQ query in C# is actually the efficient way to do it.
So, in case I wasn’t clear. This is the right code.