Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server EF4性能使用IN代替JOIN_Sql Server_Performance_Entity Framework 4_Linq To Entities - Fatal编程技术网

Sql server EF4性能使用IN代替JOIN

Sql server EF4性能使用IN代替JOIN,sql-server,performance,entity-framework-4,linq-to-entities,Sql Server,Performance,Entity Framework 4,Linq To Entities,使用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)

使用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;
            }
我关心的是将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个联合体,它们随允许的poi数递增:

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的实际解决方案吗?

在LINQ查询中确实不应该使用连接语法。我的一部分人希望他们没有在LINQ的C语言中包含join操作符,因为它只会导致混乱,并倾向于生成像这样糟糕的SQL。原因是,当您想要执行where子句或在结果中包含该表时,您几乎总是加入SQL。LINQ已经对此提供了很好的支持,但是您只需要以LINQ的方式而不是SQL的方式来思考。您的LINQ数据模型应该定义这些关系,这样您就不需要通过连接重新定义它们。在这里并不完全适用,因为您首先使用存储过程,但同样的原则也适用。您在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;
            }

我讨厌var,你最近的POI结果是什么?那么,这件事又有什么错呢?相反,最好在where表达式中使用SP.=D,使用显式类型更新问题,SP_NearestPOI返回符合radius要求的记录id的INT列表。这就是我试图归档的内容,但是我尝试生成的SQL并不是我所期望的。这是一个存储过程吗?如果是这样的话,您就不能加入存储过程的结果。thx对于这个建议,最后我创建了一个存储过程来处理这个问题,因为我还需要进行分页和筛选,而且效果很好。如果您想要分页,那么在LINQ中比在SQL中更容易。只需执行var x=POI.Skip20.Take10,其中Skip跳过前20项,Take接受20项。例如,这将是第三页的条目。
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;
            }