C# 在批处理模式下使用EF 6.1调用DbGeography距离函数

C# 在批处理模式下使用EF 6.1调用DbGeography距离函数,c#,sql-server,entity-framework,geospatial,geographic-distance,C#,Sql Server,Entity Framework,Geospatial,Geographic Distance,我在SQL Server 2014的Entity Framework 6.1中使用DbGeography类型,我需要为可能的100000个实体找到最近的位置,像下面这样一个接一个地执行时速度很慢,是否可以使用下面类似的方法,但一次执行全部操作 C#: 如果可能的话,我想在C代码中做同样的事情,而不涉及存储过程或键入SQL查询文本 平行Foreach: EntityFramework.dll中发生“System.InvalidOperationException”类型的异常,但未在用户代码中处理

我在SQL Server 2014的Entity Framework 6.1中使用DbGeography类型,我需要为可能的100000个实体找到最近的位置,像下面这样一个接一个地执行时速度很慢,是否可以使用下面类似的方法,但一次执行全部操作

C#: 如果可能的话,我想在C代码中做同样的事情,而不涉及存储过程或键入SQL查询文本

平行Foreach: EntityFramework.dll中发生“System.InvalidOperationException”类型的异常,但未在用户代码中处理
其他信息:创建模型时无法使用上下文。如果上下文在OnModelCreating方法内使用,或者如果多个线程同时访问同一上下文实例,则可能引发此异常。请注意,DbContext和相关类的实例成员不能保证线程安全。

使用并行foreach可能会对您有所帮助,因为我怀疑它获取最近邻的顺序。@BradD不幸的是,DbContext的实例成员似乎不是线程安全的。上下文不能在外部共享。您需要创建一个上下文来获取唯一位置的列表,并在并行foreach中创建、调用和处理连接使用并行foreach可能会在这方面有所帮助,因为我怀疑它获取最近邻的顺序很重要。@BradD不幸的是,DbContext的线程安全性不高。上下文不能在外部共享。您需要创建一个上下文来获取唯一位置的列表,并在并行foreach中创建、调用和处理连接
public List<GeocodableEntity> LinkToRoadNodes(List<GeocodableEntity> entities)
{
    foreach (var entity in entities)
    {
        var nearestLocation = GetNearestLocation(entity.Latitude, entity.Longitude, DEFAULT_ROAD_NODE_LINK_RADIUS);
        // update entity with values from nearestLocation
    }

    return entities;
}

private GeoLocation GetNearestLocation(float latitude, float longitude, double searchRadius)
{
    var sourcePoint = Helper.CreateDbGeographyPoint(latitude, longitude);
    return Locations.Where(x => x.Point.Distance(sourcePoint) < searchRadius)
        .OrderBy(x => x.Point.Distance(sourcePoint))
        .FirstOrDefault();
}
ALTER PROCEDURE [dbo].[GetNearestLocationNodesByCoordinates]
    @CoordinateList dbo.CoordinateListWithRefId READONLY
AS
BEGIN
    WITH InputCTE AS
    (
        SELECT RefID, geography::Point(Latitude, Longitude, 4326) AS Point
        FROM @CoordinateList
    )
    SELECT x.RefID, x.NodeId, x.Latitude, x.Longitude, x.LocationTypeId
    FROM (SELECT I.RefID as 'RefID',
                 L.NodeId,               
                 L.Point.Lat as 'Latitude',
                 L.Point.Long as 'Longitude',
                 L.LocationTypeId,
                 ROW_NUMBER() OVER (PARTITION BY I.RefID ORDER BY L.Point.STDistance(I.Point)) AS Ranking
          FROM InputCTE AS I
          JOIN Location AS L
          ON L.Point.STDistance(I.Point) <= 5000) AS x WHERE Ranking = 1
END
CREATE TYPE [dbo].[CoordinateListWithRefId] AS TABLE(
    [RefID] [int] NOT NULL,
    [Latitude] [float] NOT NULL,
    [Longitude] [float] NOT NULL
)