asp.net-mvc - 当我试图到达最近的地方时,我在运行时遇到了这个错误
问题描述
当我尝试使用实体框架工作到达最近的地方时,我在运行时遇到了这个错误
注意:我的 sql 数据库中的纬度和经度数据类型是浮点数,我在实体模型中将其映射为双精度
public JsonResult GetNearstCity(double latitude,double longitude)
{
db.Configuration.ProxyCreationEnabled = false;
var coord = new GeoCoordinate(latitude, longitude);
var nearest = db.Cities.Select(x => new GeoCoordinate(x.Latitude,x.Longtiude))
.OrderBy(x => x.GetDistanceTo(coord))
.First();
return Json(nearest, JsonRequestBehavior.AllowGet);
}
'Only parameterless constructors and initializers are supported in LINQ to Entities.'
解决方案
EF 希望将 Linq 表达式中的所有内容转换或跟踪为 SQL。SQL 不知道什么是 GeoCoordinate 对象,因此 EF 无法使用参数构造一个。您可以告诉 EF 使用默认构造函数构造一个对象,因为 EF 将从适用的表中请求字段,然后在执行查询后设置属性。
例如,这将起作用:
var nearest = db.Cities.Select(x => new GeoCoordinate
{
Latitude = x.Latitude,
Longitude = x.Longitude
});
这要求纬度和经度是地理坐标上的公共属性。
您将面临的下一个问题是您也无法GetDistanceTo(coord)
在 linq 表达式中调用。同样,EF 将无法将此方法发送到 SQL,因为 SQL 将不知道此方法是什么。这里有两种选择:
选项 1:如果数据量合理,您可以让 EF 对所有城市执行整体查询,然后从那时起您处理的是 Linq2Object,而不是 Linq2EF,因此您可以在 GeoCoordinate 上调用类函数:
var nearest = db.Cities.Select(x => new GeoCoordinate
{
Latitude = x.Latitude,
Longitude = x.Longitude
}).ToList()
.OrderBy(x => x.GetDistanceTo(coord))
.First();
通过调用.ToList()
EF 将执行我们的查询以返回所有城市。从那里,您可以使用类上的函数进行进一步计算。这种方法的缺点是您会将所有城市加载到内存中。如果您有大量数据,这将对性能和资源造成限制。
选项 2:将方法翻译成 SQL 可以理解的东西。此选项允许 EF 将您的计算转换为 SQL 可以执行的东西,它在 DB 端完成工作,然后只返回您想要的单个记录。您无需在 GeoCoordinate 实体上的方法中使用逻辑,而是在 Linq 表达式内进行计算。就像是:
var nearest = db.Cities.Select(x => new GeoCoordinate
{
Latitude = x.Latitude,
Longitude = x.Longitude
})
.OrderBy(x => Math.Abs(x.Latitude - coord.Latitude) + Math.Abs(x.Longitude - coord.Longitude))
.First();
这可能不是您要用于查找最接近的 2 点的公式,它只是类似公式的一个示例。Math.Abs()
是一种 .Net 方法,但 EF 确实知道如何将其转换为 SQL。将实体内部的逻辑用于该GetDistanceTo(coord)
方法并将其向上移动到 Linq 表达式中,您应该就差不多了。
推荐阅读
- angular - 如何设计http请求服务?我究竟做错了什么?
- jestjs - 升级 Jest 后运行测试时出错
- jmeter - 使用 JMeter 的动态请求
- c++ - 调用 C++ 基方法而不是派生方法
- python - 如何解决 c = cov(x, y, rowvar) RuntimeWarning:python 3.8 中切片错误的自由度 <= 0?
- c# - 如何解构可空元组?
- javascript - 如何在 html 中包含要使用的脚本
- javascript - 测试 SVG 路径(“d”属性)字符串是否有效
- python - Django paginator changes pages content every iteration
- .htaccess - 仅使用 .htaccess 设置 symfony4 URI