我在 SQL Server 2014 中使用 Entity Framework 6.1 中的 DbGeography 类型,我需要找到可能有 100,000 个实体的最近位置,如下所示一个一个地执行它很慢,是否可以使用与我类似的方法在下面,但一次全部完成?
C#:
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();
}
我之所以这么说是因为在此之前,我正在使用存储过程做类似的事情。
SQL中的类似:
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
@CoordinateList 在哪里:
CREATE TYPE [dbo].[CoordinateListWithRefId] AS TABLE(
[RefID] [int] NOT NULL,
[Latitude] [float] NOT NULL,
[Longitude] [float] NOT NULL
)
如果可能的话,我想在 C# 代码中做同样的事情,而无需触及存储过程或键入 SQL 查询文字。
并行 Foreach :
EntityFramework.dll 中出现“System.InvalidOperationException”类型的异常,但未在用户代码中处理附加信息:创建模型时无法使用上下文。如果在 OnModelCreating 方法中使用上下文,或者多个线程同时访问同一个上下文实例,则可能会引发此异常。请注意,不保证 DbContext 和相关类的实例成员是线程安全的。