2013-01-18 90 views
7

我有數據庫,並在其中我有班級酒店與GPS座標。我想獲得最接近我選擇的座標的位置。C# - LINQ - 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 支持到實體

我想谷歌它的d我發現將linq分成兩個可以幫助我,但我不知道如何。感謝幫助。

+0

這是目前正在做算術* *相關有一個合理的對成功的。我懷疑如果沒有很多工作,這是行不通的。你很可能想要一個存儲過程或UDF。 –

回答

6

可以使用對象初始化,而不是參數的構造函數:

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方法的問題,你能提供該方法的實現?

+0

是的,你是對的。你用無參數構造函數解決了我的問題,但是我遇到了這個方法的問題。我並不是在推動這一點。這是由GeoCoordinate類提供的方法。正如我在其他地方發現的那樣,我只有幾個算術運算允許在Linq中使用,所以我必須使用它們並找到一些算法,對嗎? –

+0

@Bibo哦,不知道GeoCoordinate是一個框架類。 Linq to Entities在內部構造一個SQL腳本,稍後將在針對IQueryable 調用ToList()時針對數據庫執行該腳本,因此您是對的,僅限於SQL數據操縱語言允許的少數操作。 – TKharaishvili

+0

@Bibo您可能會發現以下兩類有用: http://msdn.microsoft.com/en-us/library/system.data.objects.entityfunctions.aspx http://msdn.microsoft.com/ en-us/library/system.data.objects.sqlclient.sqlfunctions.aspx – TKharaishvili

4

我在這裏發佈我現在正在使用的解決方案。但我選擇GwynnBliedd答案是因爲他解決了我的問題。

我將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公式(比如this answer)。

+0

+1 - 感謝指向DbGeography類的指針!但是:我認爲您的FromText方法中經度和緯度參數的順序顛倒了;請參閱:http://stackoverflow.com/questions/16546598/dbgeography-pointfromtext-throws-latitude-values-must-be-between-90-and-90-d –

3

我已經使用數據庫這個實施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); 
相關問題