【问题标题】:Fastest way to find nearest coordinates找到最近坐标的最快方法
【发布时间】:2021-10-28 05:40:27
【问题描述】:

我有一个包含地点列表的 sqlite 数据库,我想找到离给定坐标最近的地点。

一开始我试过:

var closest = _dbContext.Places.GroupBy(x => Math.Pow((latitude - x.Latitude.Value), 2) + Math.Pow((longitude - x.Longitude.Value), 2))
            .OrderBy(x => x.Key)
            .Take(take).ToList();

但我得到了一个错误:

System.InvalidOperationException: 'The LINQ expression 'DbSet<Place>()
    .Where(m => m.Latitude.HasValue && m.Longitude.HasValue)
    .GroupBy(
        keySelector: m => Math.Pow(
            x: __latitude_0 - m.Latitude.Value, 
            y: 2) + Math.Pow(
            x: __longitude_1 - m.Longitude.Value, 
            y: 2), 
        elementSelector: m => m)' could not be translated. Additional information: Translation of method 'System.Math.Pow' failed. If this method can be mapped to your custom function, see https://go.microsoft.com/fwlink/?linkid=2132413 for more information.
Translation of method 'System.Math.Pow' failed. If this method can be mapped to your custom function, see https://go.microsoft.com/fwlink/?linkid=2132413 for more information. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to 'AsEnumerable', 'AsAsyncEnumerable', 'ToList', or 'ToListAsync'. See https://go.microsoft.com/fwlink/?linkid=2101038 for more information.'

所以为了绕过这个错误,我插入了 Where & AsEnumerable 来解决问题,但由于它非常慢。

public List<Place> GetNearestPlace(double latitude, double longitude, int take)
{
    var closest = _dbContext.Places.Where(x => x.Latitude.HasValue && x.Longitude.HasValue).AsEnumerable()
                .GroupBy(x => Math.Pow((latitude - x.Latitude.Value), 2) + Math.Pow((longitude - x.Longitude.Value), 2))
                .OrderBy(x => x.Key)
                .Take(take).ToList();
    
    IEnumerable<Place> tmp = closest.SelectMany(group => group);
    List<Place> newList = smths.ToList();

    return newList;
}

我正在寻找一种可以尽快检索数据的解决方案。

【问题讨论】:

    标签: c# sqlite entity-framework-core


    【解决方案1】:

    要复制和加快您的方法,因为您只是将值平方,您可以将标量值自己乘以实现此目的。

    var closest = _dbContext.Places
                            .OrderBy(x => (
            (latitude - x.Latitude.Value) * (latitude - x.Latitude.Value)
                                          ) + 
                                          (
            (longitude - x.Longitude.Value) * (longitude - x.Longitude.Value)
                                          )
                            )
                            
                            .Take(take)
                            .ToList();
    

    让我知道这是否适合你。

    【讨论】:

    • 我仍然收到此错误:System.InvalidOperationException: 'Unable to translate the given 'GroupBy' pattern。在“GroupBy”之前调用“AsEnumerable”以在客户端对其进行评估。'
    • 我已经更新了建议的答案并删除了 group by,上面现在将排序推送到 orderBy。我需要一些时间来复制您的设置并执行完整的测试,但是在那之前。让我知道这是否适合您。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-02-06
    • 2017-03-15
    • 1970-01-01
    • 1970-01-01
    • 2013-12-20
    • 2019-07-31
    • 1970-01-01
    相关资源
    最近更新 更多