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