【发布时间】:2021-09-04 23:59:33
【问题描述】:
我们将 ASP.NET Core 5 后端与 SQL Server v15 和 Entity Framework V5 一起使用,我一直在努力解决一些有趣的问题,请考虑一下:
你有一个如下表:
CREATE TABLE [dbo].[ContactDetails](
[Id] [int] IDENTITY(1,1) NOT NULL,
[Name] [nvarchar](128) NOT NULL,
...
[Geolocation] [geography] NULL
)
该表被其他表使用,例如。 Stores., 存储联系方式。
Table ContactDetails 会自动搭建如下:
public partial class ContactDetail
{
public ContactDetail()
{
Stores = new HashSet<Store>();
}
public int Id { get; set; }
public string Name { get; set; }
public Geometry Geolocation { get; set; }
}
然后你从输入中存储商店的经度和纬度(双精度)让我们说:
Geometry Store.ContactDetails.Geolocation = new NetTopologySuite.Geometries.Point(store.longitude, store.latitude) { SRID = 4326 };
现在给定一个来自用户的位置,它是以相同的方式创建的
Geometry userLocation = new NetTopologySuite.Geometries.Point(user.longitude, user.latitude) { SRID = 4326 };
您想知道每个商店离用户有多远。你会怎么做?
我这样做了:
DbContext dbContext; //...somehow constructed
var dbSet = dbContext.Set<Store>();
var distances = dbSet.Where(...).Select(store => store.ContactDetails.Geolocation.Distance(userLocation));
但令我惊讶的是,距离完全消失了!我希望距离以度为单位返回,我将不得不将其转换为公里。但这些数字完全不成立(如 83130)。
所以我尝试了这个:
var anotherDistances = dbSet.Where(...).AsEnumerable().Select(store => store.ContactDetails.Geolocation.Distance(userLocation));
这次距离符合预期(例如 1.245 度)。
那里发生了什么?
我需要将结果保留为IQueryable,以便我可以有效地进行进一步的过滤和转换。如何在不将IQueryable 转换为IEnumerable 的情况下获得正确的距离?
我无法从其他问题中找到答案,我怀疑 Linq 无法正确地将查询转换为 SQL,并且在 AsEnumerable() 之后的查询能够使用正确的类型推断并在加载对象时使用空间正确的方法记忆。但这只是一些模糊的理解。如果您能帮助我理解这一点,我将不胜感激。
【问题讨论】:
标签: c# sql-server entity-framework linq asp.net-core