azure移动服务-我不能让Linq比较地理距离



我得到错误:

'new GeoCoordinate(MyEntity.Lat, MyEntity.Lon).GetDistanceTo(14.4416616666667, 5.71794583333333)' is not supported in a 'Where' Mobile Services query expression.

来自以下查询:

GeoCoordinate mypos = new GeoCoordinate(MainPage.myEntity.Lat, MainPage.myEntity.Lon);
var items = await App.MobileService
                        .GetTable<MyEntity>()
                        .Where(MyEntity => MyEntity.Id != MainPage.myEntity.Id && MyEntity.IsSelected == MainPage.myEntity.IsSelected 
                            && (MyEntity.Lat != 0 && MyEntity.Lon != 0) 
                            && new GeoCoordinate(MyEntity.Lat, MyEntity.Lon).GetDistanceTo(mypos) <= 5000)
                        .Take(20)
                        .ToListAsync();

我试图从一个不是我的表中获得20个实体,并且在我位置的5公里范围内。

需要注意的一点是,行表达式不是在本地执行的。相反,它被转换成一个查询字符串发送给服务器——否则你将下载比你需要的更多的数据(顺便说一下,你仍然可以这样做)。鉴于此,没有办法将方法GeoCoordinate.GetDistanceTo转换为可以通过网络发送的内容。

服务器中支持一些操作,例如算术(+,-,*,/),您可以潜在地实现与您需要的类似的操作。类似下面的代码应该可以工作(还没有尝试过)。注意,您需要在坐标(纬度/经度)和GetDistanceTo方法返回的任何单位之间进行转换。

GeoCoordinate mypos = new GeoCoordinate(MainPage.myEntity.Lat, MainPage.myEntity.Lon);
double maxDistance = 1;
var items = await App.MobileService
    .GetTable<MyEntity>()
    .Where(e => e.Id != MainPage.myEntity.Id &&
                e.IsSelected == MainPage.myEntity.IsSelected &&
                (e.Lat != 0 && e.Lon != 0) &&
                ( ((e.Lat - mypos.Lat) * (e.Lat - mypos.Lat) +
                   (e.Lon - mypos.Lon) * (e.Lon - mypos.Lon)) < maxDistance )
    .Take(20)
    .ToListAsync();

或者,正如我之前提到的另一种选择是简单地不按调用的距离进行过滤,然后再进行过滤。类似下面的代码:

GeoCoordinate mypos = new GeoCoordinate(MainPage.myEntity.Lat, MainPage.myEntity.Lon);
List<MyEntity> items = new List<MyEntity>();
int skip = 0;
while (items.Count < 20) {
    var temp = await App.MobileService
        .GetTable<MyEntity>()
        .Where(e => e.Id != MainPage.myEntity.Id &&
                    e.IsSelected == MainPage.myEntity.IsSelected &&
                    (e.Lat != 0 && e.Lon != 0)
        .Skip(skip)
        .Take(20)
        .ToListAsync();
    if (temp.Count == 0) break;
    foreach (var item in temp)
    {
        if (new GeoCoordinate(item.Lat, item.Lon).GetDistanceTo(mypos) <= 5000)
        {
            items.Add(item);
        }
    }
}

相关内容

  • 没有找到相关文章