2013-05-03 8 views
5

LINQを使用してデータベースから近くの場所の一覧をASP.NET 2012で受信したいと考えています。LINQを使用してデータベースの近くの場所を検索


マイテーブルと偽データ:

 PlaceId Name  Latitude Longitude 
     1   A   18.1  20.1 
     2   B   18.2  20.2 
     3   C   18.3  20.3 

1)我々のプロジェクトでは、クライアントの現在位置(緯度及び経度)が入力

2とする)サーバ側で、依存してクライアントの現在の場所、LINQを使用してデータベースから近くの場所を見つける必要があります

私が以前使用したSQLのコードはここにありますが、今はLINQを使いたいと思います。

SELECT name, Latitude, Longitude , 
    (3959 * acos(cos(radians(?))* cos(radians(Latitude)) * cos(radians(Longitude) - radians(?)) 
+ sin(radians(?)) * sin(radians(Latitude)))) AS distance 
FROM TABLE_NAME 
HAVING distance < ? 
ORDER BY distance LIMIT 0 , 20 

[しかし、問題は、LINQでこのようなクエリを作成する方法である。]

この上の私の仕事:

ソリューションを探している間、私はこのコード

に出くわしました
 var Value1 = 57.2957795130823D; 
     var Value2 = 3958.75586574D; 

     var searchWithin = 20; 

    double latitude = ConversionHelper.SafeConvertToDoubleCultureInd(Latitude, 0), 
      longitude = ConversionHelper.SafeConvertToDoubleCultureInd(Longitude, 0); 

    var location = (from l in sdbml.Places 
        let temp = Math.Sin(Convert.ToDouble(l.Latitude)/Value1) * Math.Sin(Convert.ToDouble(latitude)/Value1) + 
          Math.Cos(Convert.ToDouble(l.Latitude)/Value1) * 
          Math.Cos(Convert.ToDouble(latitude)/Value1) * 
          Math.Cos((Convert.ToDouble(longitude)/Value1) - (Convert.ToDouble(l.Longitude)/Value1)) 
         let calMiles = (Value2 * Math.Acos(temp > 1 ? 1 : (temp < -1 ? -1 : temp))) 
         where (l.Latitude > 0 && l.Longitude > 0) 
         orderby calMiles 
         select new location 
          { 
            Name = l.name 
           }); 
         return location .ToList(); 

しかし、問題は、ConversionHelperの参照方法またはその名前空間の問題です。

すべてのアドバイスをいただければ幸いです。

+1

なぜストアドプロシージャを使用しないのですか?格納されたprocの結果を、テーブルをマッピングするのと同じ方法でオブジェクトにマップすることができます。 getClosePlaces_Result。 –

+0

申し訳ありませんが、もしあなたが望むなら、戻り値の型が場所のリストであることを指定することができます。 –

+0

@JuannStrauss明白なコード依存の結果とは別に、OPはC#でこれを行う方法を要求しています;-) –

答えて

2

ここでは最終的に私は

1と落ち着くしなければならないコードがある)を作成しますクラス、

DistanceModel.csは言う

public class DistanceModel 
{ 
    public int PlaceId { get; set; } 

    public string Name { get; set; } 

    public double Latitute { get; set; } 

    public double Longitude { get; set; } 

} 

2)次に、あなたがしたい方のファイルに以下のコードが含まれ、それは私のために働い

MainPage.cs

 /*Call GetAllNearestFamousPlaces() method to get list of nearby places depending 
     upon user current location. 
     Note: GetAllNearestFamousPlaces() method takes 2 parameters as input 
    that is GetAllNearestFamousPlaces(user_current_Latitude,user_current_Longitude) */ 


    public void GetAllNearestFamousPlaces(double currentLatitude,double currentLongitude) 
    { 
     List<DistanceModel> Caldistance = new List<DistanceModel>(); 
     var query = (from c in sdbml.Places 
        select c).ToList(); 
     foreach (var place in query) 
     { 
      double distance = Distance(currentLatitude, currentLongitude, place.Latitude, place.Logitude); 
      if (distance < 25)   //nearbyplaces which are within 25 kms 
      { 
       DistanceModel dist = new DistanceModel(); 
       dist.Name = place.PlaceName; 
       dist.Latitute = place.Latitude; 
       dist.Longitude = place.Logitude; 
       dist.PlaceId = place.PlaceId; 
       Caldistance.Add(getDiff); 
      } 
     }      
    } 

    private double Distance(double lat1, double lon1, double lat2, double lon2) 
    { 
     double theta = lon1 - lon2; 
     double dist = Math.Sin(deg2rad(lat1)) * Math.Sin(deg2rad(lat2)) + Math.Cos(deg2rad(lat1)) * Math.Cos(deg2rad(lat2)) * Math.Cos(deg2rad(theta)); 
     dist = Math.Acos(dist); 
     dist = rad2deg(dist); 
     dist = (dist * 60 * 1.1515)/0.6213711922;   //miles to kms 
     return (dist); 
    } 

    private double deg2rad(double deg) 
    { 
     return (deg * Math.PI/180.0); 
    } 

    private double rad2deg(double rad) 
    { 
     return (rad * 180.0/Math.PI); 
    } 

は、それがあなたを助けることを願っています、と言います。

4

だから、2つの座標間の距離を計算するだけであれば、ドットネットのGeoCoordinateを使わないのはなぜですか?

それはあなたが、名前空間System.Device.Location内でそれを見つけることができ

var firstCordinate = new GeoCoordinate(latitude1, longitude1); 
var secondCordinate = new GeoCoordinate(latitude2, longitude2); 

double distance = firstCordinate.GetDistanceTo(secondCordinate); 

のようなものです。

これにより、Math.CosMath.Sinのすべてからあなたを救うことができ、あなたのlinqは平易でシンプルになります。 (おそらく、foreachループを行います)

ので、あなたの全体のクエリのように要約することができます。

List<Location> locations = new List<Location>(); 
foreach(var place in sdbml.Places) 
{ 
    //your logic to compare various place's co-ordinates with that of 
    //user's current co-ordinate 
} 
関連する問題