IsWithinDistance 无法翻译

Ste*_*eve 4 c# spatial-query nettopologysuite entity-framework-core .net-core

我正在尝试返回给定位置 50 英里范围内的物品列表。

我的表格(简化)如下:

  • ID
  • 经度
  • 纬度
  • 地位
  • 积极的

我有一个初步询问:

var query = db.MyTable.Where(o=> o.Status == "New" && o.Active == true);

query = query.Where(o => new Point(o.Longitude, o.Latitude)
                  .IsWithinDistance(new Point(_currentLongitude, _currentLatitude), 50));

var result = query.ToList()
Run Code Online (Sandbox Code Playgroud)

但是 - 它似乎不起作用并且收到如下错误 - 有什么想法如何解决这个问题吗?或者是否有更好的方法来获取最近的物品?

.Where(p => new Point(p.Longitude, p.Latitude) .IsWithinDistance(geom: __p_3,
distance: ___maxDistance_4))' 无法翻译。

以可翻译的形式重写查询,或者通过插入对 AsEnumerable()、AsAsyncEnumerable()、ToList() 或 ToListAsync() 的调用来显式切换到客户端计算。有关详细信息,请参阅https://go.microsoft.com/fwlink/?linkid=2101038 。

启动.cs:

services.AddDbContext<AppDbContext>(options =>
{
                
 options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"),
   x => x.UseNetTopologySuite());
});
Run Code Online (Sandbox Code Playgroud)

Mat*_*int 6

要使此功能发挥作用,您需要将这些坐标存储为PointSQLgeography字段中。您可以轻松地将其作为新属性的计算列添加到现有模型中。

// on your entity
public Point Coordinates { get; }

// in your db context's OnModelCreating
  modelBuilder.Entity<YourEntity>()
    .Property(x => x.Coordinates)
    .IsRequired()
    .HasComputedColumnSql("geography::Point(Latitude, Longitude, 4326)");
Run Code Online (Sandbox Code Playgroud)

请注意,SRID 4326 是 SQL Server 支持的常用纬度/经度坐标系。 更多内容请参见此处

构建您的模型并部署到您的数据库。

现在您已经有了空间字段和属性,您可以像这样查询:

var point = new Point(_currentLongitude, _currentLatitude) { SRID = 4326 };
var distanceInMeters = 50 * 1609.344;  // 50 miles to meters conversion
var results = db.YourEntity
                .Where(x => x.Coordinates.IsWithinDistance(point, distanceInMeters))
                .ToList();
Run Code Online (Sandbox Code Playgroud)

SRID 4326 使用来表示距离,因此如果您使用英里,请务必按照上面所示进行转换。

此外,如果您有大量数据,您还需要在该列上添加空间索引,但EF Core 尚不直接支持,因此您必须直接在 SQL 中执行此操作。