entity framework 实现按照距离排序
在做项目时,经常会遇到“离我最近”这种需求。顾名思义,它需要根据用户的经纬度和事物的经纬度计算距离,然后进行排序,最后分页(当然这些操作要在数据库中进行,否则就变成假分页了)。
我们通常可以用sql语句来实现
SELECT
es_name,
es_lon,
es_lat,
ROUND(
6378.138 * 2 * ASIN(
SQRT(
POW(
SIN(
(
30.611842 * PI() / 180 - es_lat * PI() / 180
) / 2
),
2
) + COS(30.611842 * PI() / 180) * COS(es_lat * PI() / 180) * POW(
SIN(
(
104.074666 * PI() / 180 - es_lon * PI() / 180
) / 2
),
2
)
)
) * 1000
) AS distance_um
FROM
c_ershuai
ORDER BY
distance_um ASC
但是我比较习惯使用 entity framework,于是我就想着能不能用 entity framework 实现按照距离排序。
以下是我采用的方案
首先定义一个接口,用来表示具有经纬度信息的实体。
/// <summary>
/// 具有经纬度
/// </summary>
public interface IHasLngAndLat
{
/// <summary>
/// 经度
/// </summary>
double Lng { get; set; }
/// <summary>
/// 纬度
/// </summary>
double Lat { get; set; }
}
然后创建泛型类,用来包装计算的距离。
/// <summary>
/// 带距离的数据
/// </summary>
/// <typeparam name="TEntity"></typeparam>
public class DataWithDistance<TEntity>
{
/// <summary>
/// 距离(km)
/// </summary>
public double Distance { get; set; }
/// <summary>
/// 实体数据
/// </summary>
public TEntity Entity { get; set; }
}
最后编写根据距离排序的扩展方法
注意:这个方法是采用的 SqlFunctions 类,所以仅支持SqlServer数据库,如果是其它数据库,需要将 SqlFunctions 更换成对应的类
/// <summary>
/// IQueryable扩展类
/// </summary>
public static class QueryableExtension
{
/// <summary>
/// 根据距离排序
/// </summary>
/// <typeparam name="TEntity"></typeparam>
/// <param name="queryable"></param>
/// <param name="lng">经度</param>
/// <param name="lat">纬度</param>
/// <returns></returns>
public static IQueryable<DataWithDistance<TEntity>> OrderByDistance<TEntity>(this IQueryable<TEntity> queryable, double lng, double lat) where TEntity : class, IHasLngAndLat
{
var rtn = from q in queryable
let radLat1 = lat * Math.PI / 180.0
let radLat2 = q.Lat * Math.PI / 180.0
let a = radLat1 - radLat2
let b = lng * Math.PI / 180.0 - q.Lng * Math.PI / 180.0
let s = * SqlFunctions.Asin(SqlFunctions.SquareRoot(Math.Pow((double)SqlFunctions.Sin(a / ), ) +
SqlFunctions.Cos(radLat1) * SqlFunctions.Cos(radLat2) * Math.Pow((double)SqlFunctions.Sin(b / ), ))) * 6378.137
let d = Math.Round((double)s * ) /
orderby d
select new DataWithDistance<TEntity> { Entity = q, Distance = d }; return rtn;
}
}
以上就完成了 entity framework 按照距离排序的功能。
接下来我们用它来写一个小小的demo
首先创建一个商店实体类,具有经纬度字段,实现了 IHasLngAndLat 接口。
/// <summary>
/// 商店实体
/// </summary>
public class Shop : IHasLngAndLat
{
/// <summary>
/// 主键
/// </summary>
public int Id { get; set; }
/// <summary>
/// 商店名称
/// </summary>
[Required]
[StringLength()]
public string ShopName { get; set; }
/// <summary>
/// 经度
/// </summary>
public double Lng { get; set; }
/// <summary>
/// 纬度
/// </summary>
public double Lat { get; set; }
}
然后创建EF上下文类
/// <summary>
/// EF上下文
/// </summary>
public class DemoDbContext : DbContext
{
public DemoDbContext()
: base("name=DemoDbContext")
{
}
public virtual DbSet<Shop> Shop { get; set; }
}
最后我们分页查询商店,并按照距离由近到远排序
#region 入参
double user_lng = 113.46, user_lat = 22.27; //用户经纬度
int pageIndex = ; //当前页码
int pageSize = ; //每页条数
#endregion using (DemoDbContext context = new DemoDbContext())
{
var queryable = context.Shop.AsNoTracking().AsQueryable();
IQueryable<DataWithDistance<Shop>> sort_queryable = queryable.OrderByDistance(user_lng, user_lat); //按照用户的距离从近到远排序
List<DataWithDistance<Shop>> data = sort_queryable.Skip((pageIndex - ) * pageSize).Take(pageSize).ToList(); //分页并执行sql查询获取数据 //TODO:将查到的数据映射成DTO对象,并返回给客户端
}
好了,entity framework 实现按照距离排序 也就全部完成了。
entity framework 实现按照距离排序的更多相关文章
- Entity Framework实现多列排序
aList.OrderBy(a => a.WIndex).ThenBy(a=>a.KIndex) 类似sql:order by WIndex,KIndex
- 《Entity Framework 6 Recipes》中文翻译系列 (16) -----第三章 查询之左连接和在TPH中通过派生类排序
翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 3-10应用左连接 问题 你想使用左外连接来合并两个实体的属性. 解决方案 假设你有 ...
- 《Entity Framework 6 Recipes》中文翻译系列 (27) ------ 第五章 加载实体和导航属性之关联实体过滤、排序、执行聚合操作
翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 5-9 关联实体过滤和排序 问题 你有一实体的实例,你想加载应用了过滤和排序的相关 ...
- Working with Data » Getting started with ASP.NET Core and Entity Framework Core using Visual Studio » 排序、筛选、分页以及分组
Sorting, filtering, paging, and grouping 7 of 8 people found this helpful By Tom Dykstra The Contoso ...
- MVC5 Entity Framework学习参加排序、筛选和排序功能
上一篇文章实现Student 基本的实体CRUD操作.本文将展示如何Students Index页添加排序.筛选和分页功能. 以下是排序完成时.经过筛选和分页功能截图,您可以在列标题点击排序. 1.为 ...
- ASP.NET MVC with Entity Framework and CSS一书翻译系列文章之第五章:排序、分页和路由
本章的重点是对产品信息增加排序和分页的功能,以及使用ASP.NET Routing特性添加更加友好的URL支持. 注意:如果你想按照本章的代码编写示例,你必须完成第四章或者直接从www.apress. ...
- ASP.NET MVC with Entity Framework and CSS一书翻译系列文章之第二章:利用模型类创建视图、控制器和数据库
在这一章中,我们将直接进入项目,并且为产品和分类添加一些基本的模型类.我们将在Entity Framework的代码优先模式下,利用这些模型类创建一个数据库.我们还将学习如何在代码中创建数据库上下文类 ...
- 《Entity Framework 6 Recipes》中文翻译系列 目录篇 -持续更新
为了方便大家的阅读和学习,也是响应网友的建议,在这里为这个系列做一个目录.在目录开始这前,我先来回答之前遇到的几个问题. 1.为什么要学习EF? 这个问题很简单,项目需要.这不像学校,没人强迫你学习! ...
- [ASP.NET MVC 小牛之路]06 - 使用 Entity Framework
在家闲着也是闲着,继续写我的[ASP.NET MVC 小牛之路]系列吧.在该系列的上一篇博文中,在显示书本信息列表的时候,我们是在程序代码中手工造的数据.本文将演示如何在ASP.NET MVC中使用E ...
随机推荐
- Java IO--字符流--BufferedReader和BufferedWriter
从昨天开始没事情干时,决定梳理梳理Java IO流,因为觉得太混乱这个东西,妈的,咋就这么多类型,想累死谁啊,这里并不是埋怨创造者,而是气自己看着看着老跑偏,实在看不进去,太多了,想睡觉,所以现在决定 ...
- appium----【已解决】【Mac】安装sudo npm install -g appium-doctor总是提示“Error: EACCES: permission denied........”
[mac电脑] 问题: (1)npm install -g appium-doctor (2)sudo npm install -g appium-doctor (3)cnpm install ...
- 安全研究 | Jenkins 任意文件读取漏洞分析
欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 本文由云鼎实验室 发表于云+社区专栏 一.漏洞背景 漏洞编号:CVE-2018-1999002 漏洞等级:高危 Jenkins 7 月 18 ...
- .net mvc + layui做图片上传(二)—— 使用流上传和下载图片
摘要:上篇文章写到一种上传图片的方法,其中提到那种方法的局限性,就是上传的文件只能保存在本项目目录下,在其他目录中访问不到该文件.这与浏览器的安全性机制有关,浏览器不允许用户用任意的路径访问服务器上的 ...
- .net double类型转string类型的坑
之前项目当中的接入的高德逆地理编码功能偶尔会出现参数错误的bug,经过排查服务端异常log,发现请求的url中的location参数中的小数点变成了逗号. 代码如下 public async Task ...
- C# 语音合成
1. 引用System.Speech 2. 通过SpeechSynthesizer类朗读文本 new SpeechSynthesizer().SpeakAsync("我们都是好孩子We're ...
- C#设计模式整理
我居然连一月一随笔都没有,啊啊啊,忙死个人 这个随笔主要是记录基于自己学习[美]James W.Cooper著的<C# Design Patterns : A Tutorial>一书中常用 ...
- JQuery --- 第三期 (jQuery事件相关)
个人学习笔记 1.JQuery事件绑定 <!DOCTYPE html> <html lang="en"> <head> <meta cha ...
- Dynamics 365 CE中使用FetchXML进行聚合运算
微软动态CRM专家罗勇 ,回复328或者20190429可方便获取本文,同时可以在第一间得到我发布的最新博文信息,follow me! Dynamics 365 Customer Engagement ...
- Snapde一个全新的CSV超大文件编辑软件
今天介绍如果数据量超过104万行Excel无法打开了,用什么软件可以打开呢?Snapde,一个专门为编辑超大型数据量CSV文件而设计的单机版电子表格软件:它在C++语言开发的Snapman多人协作电子 ...