这是我写过的Linq to Entities Statement。
public static List<Model.User> GetNearestUsers(int userid,int count,ref Model.HangoutDBEntities context)
{
Model.Location myLocation=GetCurrentLocation(userid,ref context);
return context.Locations.Where(o => EntityFunctions.DiffMinutes(DateTime.Now, o.DateTimeStamp) <= 30).OrderBy(o => Core.Location.Distance.CalculateDistance(myLocation.Latitude, myLocation.Longitude, o.Latitude, o.Longitude)).Select(o => o.User).ToList();
}
这是CalculateDistance方法
public static double CalculateDistance(decimal lat1,decimal lon1,decimal lat2,decimal lon2)
{
try
{
var R = 6371; // Radius of the earth in km
var dLat = DegreeToRadian((double)(lat2 - lat1)); // Javascript functions in radians
var dLon = DegreeToRadian((double)(lon2 - lon1));
var a = Math.Sin(dLat / 2) * Math.Sin(dLat / 2) +
Math.Cos(DegreeToRadian((double)lat1)) * Math.Cos(DegreeToRadian((double)lat2)) *
Math.Sin(dLon / 2) * Math.Sin(dLon / 2);
var c = 2 * Math.Atan2(Math.Sqrt(a), Math.Sqrt(1 - a));
var d = R * c; // Distance in km
return (double)d;
}
catch
{
return 0.0;
}
}
public static double DegreeToRadian(double angle)
{
return Math.PI * angle / 180.0;
}
如果有任何解决方法,请告诉我。我得到一个例外
LINQ to Entities无法识别方法'Double CalculateDistance(System.Decimal,System.Decimal,System.Decimal, System.Decimal)'方法,这个方法无法翻译成一个 商店表达。
我知道自定义函数不能与Linq 2实体一起使用,但我不知道这方面的解决方法。你能帮帮我吗? :)
答案 0 :(得分:3)
将数据加载到列表中,然后在列表
上执行Caclulation var origList = context.Locations.Where(o => EntityFunctions.DiffMinutes(DateTime.Now, o.DateTimeStamp) <= 30).ToList()
var orderedList = origList.OrderBy(o => Core.Location.Distance.CalculateDistance(myLocation.Latitude, myLocation.Longitude, o.Latitude, o.Longitude)).Select(o => o.User).ToList();
或者
context.Locations
.Where(o => EntityFunctions.DiffMinutes(DateTime.Now, o.DateTimeStamp) <= 30).ToList()
.OrderBy(o => Core.Location.Distance.CalculateDistance(myLocation.Latitude, myLocation.Longitude, o.Latitude, o.Longitude))
.Select(o => o.User).ToList();
需要注意的是在where子句之后的ToList。
在调用ToList()时,数据被加载到内存中,并且排序成为Linq To Objects的任务
答案 1 :(得分:0)
查看https://stackoverflow.com/a/5971677/292787
您可以定义自定义方法...,并告诉Entity Framework如何将该方法转换为SQL
答案 2 :(得分:0)
我最近不得不解决这个问题。诀窍是对大多数语句(Math.Pow除外)使用System.Data.Entity.SqlServer中的SqlFunction而不是System.Math。
备用LINQ样式(来自/ where / let / orderby等)非常有用,因为let关键字允许您分解问题并保持可读性。
var closestLocation = await (
from q in qryable
where q.LAT.HasValue && q.LONG.HasValue
// Convert derees to radians (pi / 180 = 0.01745...)
let dbLatitudeRadians = q.LAT.Value * 0.0174532925199433
let dbLongitudeRadians = q.LONG.Value * 0.0174532925199433
let requestLatitudeRadians = requestLatitude * 0.0174532925199433
let requestLongitudeRadians = requestLongitude * 0.0174532925199433
let deltaLatitudeRadians = requestLatitudeRadians - dbLatitudeRadians
let deltaLongitudeRadians = requestLongitudeRadians - dbLongitudeRadians
let sinHalfLatitudeDistance = SqlFunctions.Sin(deltaLatitudeRadians / 2) ?? 0.0
let sinHalfLongitudeDistance = SqlFunctions.Sin(deltaLongitudeRadians / 2) ?? 0.0
let cosThisLatitude = SqlFunctions.Cos(dbLatitudeRadians) ?? 0.0
let cosThatLatitude = SqlFunctions.Cos(requestLatitudeRadians) ?? 0.0
let expr = Math.Pow(sinHalfLatitudeDistance, 2) + cosThisLatitude * cosThatLatitude * Math.Pow(sinHalfLongitudeDistance, 2)
let sqrtExpr = Math.Pow(expr, 0.5)
let sqrt1MinusExpr = Math.Pow(1 - expr, 0.5)
let distanceInMeters = 6376500 * 2 * SqlFunctions.Atan2(sqrtExpr, sqrt1MinusExpr)
orderby distanceInMeters
select q
).FirstOrDefaultAsync(cancellationToken).ConfigureAwait(false);