至於有人提議上面添加db.DoctorsPrivateClinics.AsEnumerable()是什麼解決了我的問題。在這裏提高一點點我的功能後的解決方案:
double longitude=0;
double latitude=0;
var city = from c in db.Cities
where c.Code == Convert.ToInt32(Request.QueryString["Area"])
select c;
city = city.Take(1);//take the first value, that sould be the only value in this case
if (city.Count() == 0)
{
//hanlde error
}
else
{
City cit = city.First();
Calculations.GetLongitudeLatitudeGoogle getLongLat = new Calculations.GetLongitudeLatitudeGoogle();
getLongLat.GetLongitudeLatitude("", cit.Name, "", out longitude, out latitude);
}
var doctorPractise = from d in db.DoctorsPrivateClinics.AsEnumerable()//or .ToList()
where CalcualateDistance(Convert.ToDouble(d.PrivateClinic.Latitude), Convert.ToDouble(d.PrivateClinic.Longtitude), latitude, longitude)<5.0f
select d;
其中函數CalcualateDistance是:
{
/*
The Haversine formula according to Dr. Math.
http://mathforum.org/library/drmath/view/51879.html
dlon = lon2 - lon1
dlat = lat2 - lat1
a = (sin(dlat/2))^2 + cos(lat1) * cos(lat2) * (sin(dlon/2))^2
c = 2 * atan2(sqrt(a), sqrt(1-a))
d = R * c
Where
* dlon is the change in longitude
* dlat is the change in latitude
* c is the great circle distance in Radians.
* R is the radius of a spherical Earth.
* The locations of the two points in
spherical coordinates (longitude and
latitude) are lon1,lat1 and lon2, lat2.
*/
double dDistance = Double.MinValue;
double dLat1InRad = Lat1 * (Math.PI/180.0);
double dLong1InRad = Long1 * (Math.PI/180.0);
double dLat2InRad = Lat2 * (Math.PI/180.0);
double dLong2InRad = Long2 * (Math.PI/180.0);
double dLongitude = dLong2InRad - dLong1InRad;
double dLatitude = dLat2InRad - dLat1InRad;
// Intermediate result a.
double a = Math.Pow(Math.Sin(dLatitude/2.0), 2.0) +
Math.Cos(dLat1InRad) * Math.Cos(dLat2InRad) *
Math.Pow(Math.Sin(dLongitude/2.0), 2.0);
// Intermediate result c (great circle distance in Radians).
double c = 2.0 * Math.Asin(Math.Sqrt(a));
// Distance.
// const Double kEarthRadiusMiles = 3956.0;
const Double kEarthRadiusKms = 6376.5;
dDistance = kEarthRadiusKms * c;
return dDistance;
}
即使這個工作形成我來說不使用LINQ的有效途徑。所以,我搜索了一個更好的解決辦法是重新寫我的功能在T-SQL這樣的改進方案是:
double longitude=0;
double latitude=0;
var city = from c in db.Cities
where c.Code == Convert.ToInt32(Request.QueryString["Area"])
select c;
city = city.Take(1);//take the first value, that should be the only value in this case
if (city.Count() == 0)
{
//hanlde error
}
else
{
City cit = city.First();
Calculations.GetLongitudeLatitudeGoogle getLongLat = new Calculations.GetLongitudeLatitudeGoogle();
getLongLat.GetLongitudeLatitude("", cit.Name, "", out longitude, out latitude);
}
var doctorPractise = from d in db.DoctorsPrivateClinics
where db.CalculateDistance(Convert.ToDouble(d.PrivateClinic.Latitude), Convert.ToDouble(d.PrivateClinic.Longtitude), latitude, longitude) < 5.0f
select d;
凡寫在T-SQL的功能是:
ALTER FUNCTION PublicSiteDBUser.CalculateDistance
(
@latitudeArea float(53),
@longitudeArea float(53),
@latitudePractise float(53),
@longitudePractise float(53)
)
RETURNS float(53)
AS
BEGIN
DECLARE @dDistance as float(53)=0
DECLARE @dLat1InRad as float(53)=0
DECLARE @dLong1InRad as float(53)=0
DECLARE @dLat2InRad as float(53)=0
DECLARE @dLong2InRad as float(53)=0
DECLARE @dLongitude as float(53)=0
DECLARE @dLatitude as float(53)=0
DECLARE @a as float(53)=0
DECLARE @c as float(53)=0
DECLARE @kEarthRadiusKms as float(53)=6376.5
SET @dLat1InRad = @latitudeArea * PI()/180.0
SET @dLong1InRad= @longitudeArea * PI()/180.0
SET @dLat2InRad= @latitudePractise * PI()/180.0
SET @dLong2InRad= @longitudePractise * PI()/180.0
SET @dLongitude = @dLong2InRad - @dLong1InRad
SET @dLatitude = @dLat2InRad - @dLat1InRad
SET @a = POWER(SIN(@dLatitude/2.0), 2.0)+COS(@dLat1InRad)*COS(@dLat2InRad) * POWER (SIN(@dLongitude/2.0),2.0)
SET @c = 2.0*ASIN(SQRT(@a))
SET @dDistance = @kEarthRadiusKms * @c
RETURN @dDistance
END
「似乎沒有工作」的意思是什麼? – dtb
如果我沒有行,我的結果將是相同的:其中GetDistance(db,d)<1.0 – orestispan
數據庫提供程序如何將您的C#函數轉換爲SQL?我不知道是否有更新,更強大的解決方案,但對於初學者,請查看模型定義的功能。 http://blogs.msdn.com/b/efdesign/archive/2009/01/07/model-defined-functions.aspx –