EF4使用IN代替JOIN的性能

问题描述

| 关于使用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,100000) on c.id  equals i.Value
          select c;
但是它给出了一个非常混乱的查询,该查询具有N个并集,该并集的数量随着allowedPois的数量增加
SELECT 
[Extent1].[id] AS [id],[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查询坚持我的实际解决方案?     

解决方法

        您确实不应该在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;
            }