C# – LINQ – GPS纬度和经度的最短距离

我有数据库,在其中我有gps坐标的class级酒店。 我想获得最接近我选择的坐标的位置。

我认为它看起来应该是这样的(我在这里发现了许多示例代码并且像这样):

var coord = new GeoCoordinate(latitude, longitude); var nearest = (from h in db.hotels let geo = new GeoCoordinate(h.gps.lat, h.gps.lng) orderby geo.GetDistanceTo(coord) select h).Take(10); 

问题是当我尝试搜索某些内容时出现此错误:

LINQ to Entities中仅支持无参数构造函数和初始值设定项

我试图谷歌它,我发现将linq分成两个可以帮助我,但我不知道如何。 感谢帮助。

您可以使用对象初始值设定项而不是参数化构造函数:

 var nearest = (from h in db.hotels let geo = new GeoCoordinate{ Latitude = h.gps.lat, Longitude = h.gps.lng} orderby geo.GetDistanceTo(coord) select h).Take(10); 

但是你可能会遇到GetDistanceTo方法引起的问题,你能提供该方法的实现吗?

我在这里发布我现在使用的解决方案。 但我选择了GwynnBliedd的答案,因为他解决了我的问题。

我在我的class级添加了DbGeography类型,我使用它而不是在数据库中保存纬度和经度。

 locationField = DbGeography.FromText(String.Format("POINT({0} {1})", orig.gps.lat.ToString().Replace(",", "."), orig.gps.lng.ToString().Replace(",", "."))); 

然后使用linq很容易:

 var coord = DbGeography.FromText(String.Format("POINT({0} {1})", latitude.ToString().Replace(",", "."), longitude.ToString().Replace(",", "."))); var nearest = (from h in db.hotels where h.location != null orderby h.location.Distance(coord) select h).Take(limit); return nearest; 

目前这是一个有效的解决方案,这很好。 有一段时间我会使用这个,但很少有用户在这里说我可能会尝试UDF实现Haversine公式(就像在这个答案中 )。

使用Haversine Distance公式的这种实现,我已经有了合理的成功

 var startPoint = new { Latitude = 1.123, Longitude = 12.3 }; var closest = entities.Something.OrderBy(x => 12742 * SqlFunctions.Asin(SqlFunctions.SquareRoot(SqlFunctions.Sin(((SqlFunctions.Pi() / 180) * (x.Latitude - startPoint.Latitude)) / 2) * SqlFunctions.Sin(((SqlFunctions.Pi() / 180) * (x.Latitude - startPoint.Latitude)) / 2) + SqlFunctions.Cos((SqlFunctions.Pi() / 180) * startPoint.Latitude) * SqlFunctions.Cos((SqlFunctions.Pi() / 180) * (x.Latitude)) * SqlFunctions.Sin(((SqlFunctions.Pi() / 180) * (x.Longitude - startPoint.Longitude)) / 2) * SqlFunctions.Sin(((SqlFunctions.Pi() / 180) * (x.Longitude - startPoint.Longitude)) / 2)))).Take(5);