我不能让Linq比较地理距离吗? [英] I cant make Linq compare geodistances?

查看:88
本文介绍了我不能让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公里以内.

I'm trying to get 20 entities from a table that is not me and within 5 km of my position.

推荐答案

您需要注意的一件事是,该行表达式不是在本地执行的.而是将其转换为发送给服务器的查询字符串-否则,您将下载比所需更多的数据(顺便说一下,您仍然可以这样做).鉴于此,无法将方法GeoCoordinate.GetDistanceTo转换为可以通过网络发送的内容.

One thing you need to be aware is that the line expression is not executed locally. It's instead translated into a query string which is sent to the server - otherwise you'd be downloading a lot more data than you need (which you still can do, by the way). Given that, there's no way to translate the method GeoCoordinate.GetDistanceTo into something which can be sent over the wire.

服务器中支持某些操作,例如算术(+,-,*,/),您可能会实现与所需功能类似的功能.像下面的代码这样的东西应该可以工作(还没有尝试过).请注意,您需要在坐标距离(经度/经度)和GetDistanceTo方法返回的任何单位之间进行转换.

There are some operations which are supported in the server, such as arithmetic (+, -, *, /), and you could potentially implement something similar to what you need. Something like the code below should work (haven't tried it yet). Notice that you'll need to do the conversion between distance in coordinates (lat / lon) and whatever unit is returned by the GetDistanceTo method.

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();

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

Or, another alternative as I mentioned before would be to simply not to filter by the distance on that call, and filter it afterwards. Something like the code below:

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);
        }
    }
}

这篇关于我不能让Linq比较地理距离吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆