2012-05-10 58 views
0

好的,这是我的问题。我有数据库表BloodCenters,其中有latitudelongitude字段。我想通过使用Linq Lambda Syntax通过检索相对于某点的给定半径内的BloodCenters来查询这些表。如何在Lambda .NET中调用用户定义函数语法

我使用此代码,但它仍然给我的错误(如果谓词中):

public static List<BloodCenter> GetAllNearby(int latitude, int longitude, int radius, int limit){ 
    List<BloodCenter> res = null; 
    res = new DBEntities().BloodCenters.Where(b => 
     Util.distance(latitude, longitude, b.Latitude, b.Longitude, "K") <= radius).Take(limit); 
    return res; 
} 

Util.distance是2点的经度和纬度的回归之间的距离的函数。 编辑 所以,我不能把我自己的函数放在Where谓词中。但是,我可以使用SQL语法计算距离吗?这是我的Util.Distance实现:

public static double distance(double lat1, double longi1, double lat2, double longi2, string unit){ 
    var theta = longi1 - longi2; 
    var dist = Math.Sin(DegreeToRadian(lat1)) * Math.Sin(DegreeToRadian(lat2)) + 
     Math.Cos(DegreeToRadian(lat1)) * Math.Cos(DegreeToRadian(lat2)) * Math.Cos(DegreeToRadian(theta)); 
    dist = Math.Acos(dist); 
    dist = RadianToDegree(dist); 
    var miles = dist * 60 * 1.1515; 
    unit = unit.ToUpper(); 
    if (unit.Equals("K")) 
     return miles * 1.609344; 
    else if (unit.Equals("N")) 
     return miles * 0.8684; 
    else 
     return miles; 
} 
+1

纬度和经度'int'的? –

+0

你应该尝试使用sql server空间数据类型而不是一些托管代码函数 –

回答

1

这是行不通的,因为Util.distance在你的C#代码实现的,查询表面不知道如何将被转换为SQL(或者即使是可能的)。

一个直接的解决方法是从数据库中获取的所有记录和谓词适用于情况下,像这样:

res = new DBEntities().BloodCenters.ToList() 
      .Where(b => Util.distance(latitude, longitude, b.Latitude, b.Longitude, "K") <= radius) 
      .Take(limit); 
return res; 

当然,获取所有的记录是不是最好的主意要么,但有时也有根本别无退路。

您可以尝试的是在Where谓词内嵌入Util.distance的逻辑。如果只用“简单”操作(如基本数学)就可以表达逻辑,则查询表面将能够将其转换为SQL,一切都将顺利进行。

Here是可以自动转换为SQL的所有方法的列表。

+0

感谢您的解释。不幸的是我没有在你的链接上看到任何三角函数。我通过给出'Util.Distance'实现的细节来编辑我的问题。 –

0

您必须将DBEntities().BloodCenters转换为IEnumerableList或本地存储的其他东西。 Linq to SQL将C#转换为SQL - 因此您只能使用由SQL Server提供的函数。

另一种方法是模拟与翻译语句的功能,或在数据库实现它(存储过程或类似)

相关问题