SQL Server .NET Core 6 /实体框架核心中的地理SQL类型支持

jum4pzuy  于 2023-01-25  发布在  .NET
关注(0)|答案(1)|浏览(148)

我有一个.NET Core 6应用程序和SQL Server数据库,其中有一个表,表中的列定义为Geography类型。
我的目标是使用Linq查询来检索一个行列表,其中从一个点到Geography Distance〈4000米。
以下T-SQL工作正常:

-- SPATIAL WITHIN DISTANCE
DECLARE @Origin GEOGRAPHY,
        -- distance defined in meters
        @Distance INTEGER = 40000;        

-- center point
SET @Origin = GEOGRAPHY::STGeomFromText('POINT(-93.5663 44.9033)', 4326);

-- return all rows from events in 40km radius
SELECT * FROM dbo.GeographyAreas WHERE @Origin.STDistance(Geography) <= @Distance;

我更愿意在应用程序数据层中实现这段代码,并使用LINQ语法,而不是使用上述代码的存储过程。但SQL Server Geography列类型与Microsoft提供的空间库之间似乎存在不匹配:

Microsoft.EntityFrameworkCore.SqlServer.NetTopologySuite
NetTopologySuite.Core
Microsoft.Spatial
Microsoft.SqlServer.Types

NetTopologySuite支持Geometry类型,但从我所看到的来看,Geography不支持。
Microsoft.SpatialGeography类型不会Map到SQL Server Geography类型。
Microsoft.SqlServer.Types似乎是为.NET(经典)而不是.NET核心。
我正在寻找更像这样的东西:

public class GeographyAreas()
{
   public <SomeGeographyType> Geography { get; set; }
}

var origin = <SomeGeographyType>(-93.123, 44.456);
var dist = 40000;

List<GeographyAreas> results = _context.GeographyAreas.Where(x => x.Geography.Distance(origin) < dist).ToList();

其中,<SomeGeographyType>是以下任意项的占位符:

Microsoft.EntityFrameworkCore.SqlServer.NetTopologySuite
Microsoft.Spatial

当我使用这种方法时,我得到一个错误:
无法MapGeographicAreas.Geography的Geography属性,因为数据库提供程序不支持此类型
是否可以在EntityFrameworkCore中实现这一点,或者使用上面的T-SQL代码实现存储过程是否有意义?

goqiplq2

goqiplq21#

我自己解决了这个问题。事实证明,有一个视频描述了NetTopologySuite的地理方面。它被故意遗漏了(但需求以一种公认的迂回方式解决了)。
根据此视频here,在实体框架中创建模型时,要使用的数据类型是几何(即使对于Geography SQL Server数据类型)。NetTopologySuite团队决定不添加特定于Geography的功能,因为事实上,用于处理Geography和Geometry的代码是相同的。这并不是说基于全局的Geography值与笛卡尔坐标值相同-基于几何的一种;只是对它们进行操作的代码是相同的。
事实上,我能够得到这个工作使用LINQ查询。如果有兴趣,我会张贴在这里的完整解决方案。

相关问题