2010-03-04 47 views
2

我從搜索頁面獲得這條MySQL語句,用戶輸入那裏的郵政編碼,並在輸入的郵政編碼的15英里內找到最近的sticklist。用linq或亞音速計算距離

SELECT * , (
(
ACOS(SIN("+SENTLNG +" * PI() /180) * SIN(s_lat * PI() /180) + COS(" + SENTLNG +" * PI() /180) * COS(s_lat * PI() /180) * COS((
" + SENTLANG + " - s_lng 
) * PI() /180)) *180/PI() 
) *60 * 1.1515 
) AS distance_miles 
FROM new_stockists 
WHERE s_lat IS NOT NULL 
HAVING distance_miles <15 
ORDER BY distance_miles ASC 
LIMIT 0 , 15 

,但現在我使用LINQ和亞音速,並沒有得到一個線索怎麼辦爲此在LINQ或亞音速 你的幫助會非常讚賞,也請不,我已經在從地址動態發送,多數民衆贊成在網頁頂部提到的郵政編碼,我打電話給谷歌,然後從他們的lng和拉特給出的郵編。

回答

2

您可以創建在MS SQL,做您的查詢所做的一個存儲過程,然後從你的應用程序調用查詢。 LINQ的不支持存儲過程 - kindof這樣

partial class StockistsDataContext 
{ 
    [Function(Name = "dbo.NewStockistsByDistance")] 
    public ISingleResult<NewStockist> NewStockistsByDistance(
     [Parameter(DbType = "Int", Name = "s_lat")] int lat, 
     [Parameter(DbType = "Int", Name = "s_lng")] int lng) 
    { 
     var result = this.ExecuteMethodCall(this, ((MethodInfo)(MethodInfo.GetCurrentMethod())), lat, lng); 
     return ((ISingleResult<NewStockist>)(result.ReturnValue)); 
    } 
} 

這是一個有點刺激性回落到存儲的特效,但我不認爲解析Queryables expressiontrees LINQ的部分可以檢測revant數學函數和地圖他們到SQL。

+0

嗯有效點羞恥亞音速仍然沒有實際創建代碼爲mysql存儲過程從來沒有真的但那是defo一個選項,並將使我能夠傳遞lng和lat的值....好吧,謝謝我認爲我會將此標記爲答案。 – davethecoder 2010-03-05 14:07:39

-1

建立在SQL Server中使用SQL的這一部分的新觀點:

SELECT * , (your equation here) as distance 
FROM new_stocklists 
WHERE s_lat is not NULL 

然後,你可以爲你的視圖中創建一個LINQ對象(SQLMetal將做到這一點或LINQ在Visual Studio,SQL)。然後你可以使用Linq來查詢這個視圖。比方說,你的目標是StockDistance:

var list = db.StockDistance.Where(x=>x.distance<15) 
    .OrderBy(x=>x.distance) 
    .Take(15); 
+0

嘗試,但如果你看到該方程採取的LNG和緯度爲出發點,或者你去哪兒得到你的距離點,已經想到了一個視圖,沒有實際發送一個初始的起點,沒有辦法計算你上面做的是重新創建我的表,但在一個視圖和額外的距離的領域,但只有從一個設置點,但感謝您的輸入 – davethecoder 2010-03-04 22:55:23

0

我建議(如果可能)獲取郵編的中心點,然後應用Haversine公式來查找某個半徑內的所有商店。

這裏的公式是以公里爲單位。
你將不得不改變相關的數字,它將工作數英里。
例如:將6371.392896轉換爲英里。

DECLARE @radiusInKm AS FLOAT
DECLARE @ lat2Compare AS FLOAT
DECLARE @ long2Compare AS FLOAT
SET @radiusInKm = 5.000
SET @ lat2Compare = insert_your_lat_to_compare_here
SET @ long2Compare = insert_you_long_to_compare_here

SELECT * FROM insert_your_table_here WITH(NOLOCK) WHERE(6371.392896 * 2 * ATN2(SQRT((sin((radians(GeoLatitude - @ lat2Compare))/ 2)* sin ((弧度(GeoLitudeitude - @ lat2Compare))/ 2))+(cos(弧度(GeoLatitude))* cos(弧度(@ lat2Compare))* sin(弧度(GeoLongitude - @ long2Compare)/ 2)* sin(弧度((radians(GeoLatitude - @ lat2Compare))/ 2)* sin((radians(GeoLitudeitude - @ lat2Compare))/ 2))+((GeoLongitude - @ long2Compare)/ 2))) ,SQRT cos(弧度(GeoLatitude))* cos(弧度(@ lat2Compare))* sin(弧度(GeoLongitude - @ long2Compare)/ 2)* sin(弧度(GeoLongitude - @ long2Compare)/ 2)))< = @radiusInKm

如果你想執行在C#haversine公式,

雙resultDistance = 0.0;
double avgRadiusOfEarth = 6371.392896; //地球的半徑不同,我正在取平均值。

//半正矢式
//距離= R * 2 * ATAN2(A的平方根,平方根的1 - A)
//其中A =竇的平方(在緯度/ 2的差)+ (緯度1的餘弦*緯度2的餘弦*竇的平方(在經度差/ 2))
//和R =地球的圓周

雙differenceInLat = DegreeToRadian(currentLatitude - latitudeToCompare);
double differenceInLong = DegreeToRadian(currentLongitude --longtitudeToCompare);數學公式(DegreeToRadian(currentLatitude))* Math.Cos(DegreeToRadian(latitudeToCompare))* Math.Sin(differenceInLong/2)* Math.Sin(differenceInLong/2);數學公式(公式2)
double aFormula =(Math.Sin((differenceInLat)/ 2)* Math.Sin((differenceInLat)/ 2))+(aInnerFormula);
resultDistance = avgRadiusOfEarth * 2 * Math.Atan2(Math.Sqrt(aFormula),Math.Sqrt(1-aFormula));

DegreesToRadian是我自定義創建的函數。
它是一個簡單的1個襯墊的 「Math.PI *角度/ 180.0」

對於LINQ,可以使用C#的數學函數,以及所有C#檢查。例如:!=等於不等於等。
請參閱以下內容作爲示例。
它不完整,所以請按照您的喜好調整它。

VAR linqQuery =從linqCollection在 insert_your_collection_here
其中S-LAT!=什麼
選擇Math.ACos(Math.Sin(DegreesToRadian(sentlng) * Math.Pi/180))

查看下面的MSDN鏈接,瞭解所有簡單的LINQ示例。有玩它,希望這有助於

My blog entry - SQL Haversine

MSDN - 101 LINQ Samples