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 ...
随机推荐
- python 格式化输出日志记录
# 格式化打印提示输出示例已logging模块为例. service_name = "Booking" logger.error('%s service is down!' % s ...
- jquery中attr()和prop()的区别
最近项目回归使用jquery,页面渲染全是使用jquery做的,所以做的时候也遇到了许多以前没有见过的问题,如这次操作[radio]控件的"checked"属性时有遇到问题, $( ...
- 微服务架构 - 解决Docker-Compose服务编排启动顺序问题
基于Docker Compose进行服务编排时,一定碰到服务启动顺序的问题,例如:B服务启动之前,A服务要已经启动并且可以正常对外服务. 这个启动顺序的问题,Docker Compose本身它是无法解 ...
- C#读写EXCEL单元格的问题
最近, 我在用C#开发一个EXCEL Add-In的时候,发现了一些害人不浅的坑,特来总结列举如下: 这里我读写EXCEL引用的是using Excel = Microsoft.Office.Inte ...
- CSharpGL(49)试水OpenGL软实现
CSharpGL(49)试水OpenGL软实现 CSharpGL迎来了第49篇.本篇内容是用C#编写一个OpenGL的软实现.暂且将其命名为SoftGL. 目前已经实现了由Vertex Shader和 ...
- 用python复制图片、视频
图片复制 f_src = open('1.jpg','rb') content = f_src.read() f_copy = open('1-副本.jpg','wb') f_copy.write(c ...
- 正则表达式在Java中的使用
目录 介绍 从简单例子认识正则表达式匹配 Java中对正则表达式的支持(各种语言有相应的实现) 初步认识 . + * ? 范围 认识\s \w \d - 下面介绍数字和字母的正则表达, 这是编程中使用 ...
- Django学习之十三:提高页面开发效率减少冗余的模板系统
目录 Django 模板 模板语法 逻辑语法 函数式过滤器 内置filter 功能tag 注释 内置tag 导入三方tag and filter(load) 过滤器和功能tag的区别 自定义tag和f ...
- 《SQL CookBook 》笔记-第二章-查询结果排序
目录 第二章 查询结果排序 2.1 以指定顺序返回查询结果 2.2 依据子串排序 2.3 排序时对 Null 值的处理 2.4 依据条件逻辑动态调整排序项 第二章 shanzm 第二章 查询结果排序 ...
- 探索JS引擎工作原理
JavaScript 从定义到执行,JS引擎在实现层做了很多初始化工作,因此在学习 JS 引擎工作机制之前,我们需要引入几个相关的概念:执行环境栈.全局对象.执行环境.变量对象.活动对象.作用域和作用 ...