EF LINQ 空间查询在 SQL 服务器中使用 Contains() 方法超时
EF LINQ spatial query times out using Contains() method in SQL Server
我有一个使用 LINQ(lambda 语法)的空间查询 (SQL Server 2012),它在大约 30 秒后超时,我无法弄清楚原因。我已经检查了索引和 运行 Tuning Advisor,但索引似乎都是有序的。我只是想获取包含给定 2D 点的多边形。
PointXY point = new PointXY(x, y);
Parcel parcel = db.parcels.Where(p => p.Geom.Contains(point)).FirstOrDefault();
我已尝试将查询重新排列为使用 Within()
方法,结果相同:
Parcel parcel = db.parcels.Where(p => point.Within(p.Geom)).FirstOrDefault();
但是,如果我只是请求计算匹配多边形的数量,则会立即返回(正确的)结果。
int count = db.parcels.Where(p => point.Within(p.Geom)).Count();
我不知道如何解决这个问题,想知道我的方法是否存在根本性错误。
您当前 无法使用Entity Framework (EF6) 指定索引提示,因此我永远无法强制使用空间索引。可能有一种方法可以更改我的 LINQ 查询以欺骗 EF 使用空间索引,但我找不到方法。我的解决方案是绕过 EF 并通过 SQLquery()
.
使用原始 SQL
string sql = "SELECT * FROM [dbo].[parcels] WITH(INDEX([idx_spatial])) WHERE (GEOMETRY::Point(@x, @y, 2193).STWithin([shape])) = 1";
var args = new DbParameter[]
{
new SqlParameter { ParameterName = "x", Value = point.XCoordinate },
new SqlParameter { ParameterName = "y", Value = point.YCoordinate },
};
Parcel parcel = db.Database.SqlQuery<Parcel>(sql, args).FirstOrDefault();
我找不到将 geometry
类型作为参数传递的方法,因此单独传递了 x/y 坐标。
我有一个使用 LINQ(lambda 语法)的空间查询 (SQL Server 2012),它在大约 30 秒后超时,我无法弄清楚原因。我已经检查了索引和 运行 Tuning Advisor,但索引似乎都是有序的。我只是想获取包含给定 2D 点的多边形。
PointXY point = new PointXY(x, y);
Parcel parcel = db.parcels.Where(p => p.Geom.Contains(point)).FirstOrDefault();
我已尝试将查询重新排列为使用 Within()
方法,结果相同:
Parcel parcel = db.parcels.Where(p => point.Within(p.Geom)).FirstOrDefault();
但是,如果我只是请求计算匹配多边形的数量,则会立即返回(正确的)结果。
int count = db.parcels.Where(p => point.Within(p.Geom)).Count();
我不知道如何解决这个问题,想知道我的方法是否存在根本性错误。
您当前 无法使用Entity Framework (EF6) 指定索引提示,因此我永远无法强制使用空间索引。可能有一种方法可以更改我的 LINQ 查询以欺骗 EF 使用空间索引,但我找不到方法。我的解决方案是绕过 EF 并通过 SQLquery()
.
string sql = "SELECT * FROM [dbo].[parcels] WITH(INDEX([idx_spatial])) WHERE (GEOMETRY::Point(@x, @y, 2193).STWithin([shape])) = 1";
var args = new DbParameter[]
{
new SqlParameter { ParameterName = "x", Value = point.XCoordinate },
new SqlParameter { ParameterName = "y", Value = point.YCoordinate },
};
Parcel parcel = db.Database.SqlQuery<Parcel>(sql, args).FirstOrDefault();
我找不到将 geometry
类型作为参数传递的方法,因此单独传递了 x/y 坐标。