9

我有数据库,其中有带 gps 坐标的类酒店。我想获得离我选择的坐标最近的地方。

我认为它应该看起来像这样(我在这里找到了很多示例代码,并且喜欢这个):

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 分成两部分可以帮助我,但我不确定如何。感谢帮助。

4

3 回答 3

7

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

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 方法引起的问题,您能否提供该方法的实现?

于 2013-01-18T16:07:06.297 回答
5

使用Haversine距离公式的这种实现,我已经取得了合理的成功

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);
于 2015-07-27T10:54:08.737 回答
4

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

我在课堂上添加了 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 公式(就像在这个答案中一样)。

于 2013-01-21T18:43:50.427 回答