我们可以将位置 SQL 转换为 C# LINQ 吗?

Posted

技术标签:

【中文标题】我们可以将位置 SQL 转换为 C# LINQ 吗?【英文标题】:Can we Convert location SQL to C# LINQ? 【发布时间】:2021-08-26 03:01:27 【问题描述】:

这是一个返回 30 英里半径内的用户列表的 SQL 语句

SELECT
    id, (
      3959 * acos (
      cos ( radians(78.3232) )
      * cos( radians( lat ) )
      * cos( radians( lng ) - radians(65.3234) )
      + sin ( radians(78.3232) )
      * sin( radians( lat ) )
    )
) AS distance
FROM users
HAVING distance < 30
ORDER BY distance

我正在使用 C# .NET Web API2,是否可以将上面的内容转换为 LINQ 语句,以便我们可以让 API 获取这些数据?

【问题讨论】:

根据问题指南,请展示您的尝试并告诉我们您发现了什么(在本网站或其他地方)以及为什么它不能满足您的需求。 没有什么能阻止你使用 dapper 和直接使用你的 sql LINQPad 可能 此查询无法编译:HAVING 应该是 WHERE,或者应该是 GROUP BY id, lat, lng。此外,除非distance 存在于表中,否则它需要APPLY 或派生表 你可以在你的 api 后面使用实体框架。然后你可以只使用 linq 来表示那个 sql 语句。有很多关于如何添加实体框架的教程。 【参考方案1】:

首先你需要为弧度定义这个方法

    public static double Radians(double angle)
    
        return (Math.PI / 180) * angle;
    

现在,您可以使用此查询

        var distances = users
            .Where(x => x.YourFilterOnPagination)
            .ToList() // your collection most be List 
            .Select(x => new
            
                id = x.id,
                distance = (395 * Math.Acos(Math.Cos(Radians(78.3232)) *
                            Math.Cos(Radians(x.lat)) * Math.Cos(Radians(x.lat) - Radians(65.3234)) +
                            Math.Sin(Radians(78.3232)) *
                            Math.Sin(Radians(x.lat))))
            )
            .Where(d => d.distance < 30)
            .OrderBy(d => d.distance);

YourFilterOnPagination:如果您的数据很大,您可以将其限制在 w

【讨论】:

就像一个魅力,我相信第一个 x.lat 应该是 x.long,在我做出这个改变之后,它就像一个魅力!再次感谢您!

以上是关于我们可以将位置 SQL 转换为 C# LINQ 吗?的主要内容,如果未能解决你的问题,请参考以下文章

C# 将带有 Case 语句的 SQL 查询转换为 LINQ

使用相同的 SQL 生成输出将 T-SQL 转换为 Fluent Linq C#

将 T-SQL string_agg 转换为 LINQ C#

将 Oracle SQL 转换为 LLBLGEN LINQ 表达式 C#

在 C# 中将 SQL 查询转换为 LINQ 方法语法

如何使用 SUM 计算将 SQL 转换为 Linq