C# 使用带有响应模式的地理坐标在x英里内获得结果
我希望获得用户输入位置x英里范围内的所有组织的列表。这将转换为长/横向位置 组织以long和lat存储在数据库中 我使用带有实体框架的MVC和带有respository模式的工作单元来访问数据集 这是我的真实陈述:C# 使用带有响应模式的地理坐标在x英里内获得结果,c#,model-view-controller,geolocation,repository-design,C#,Model View Controller,Geolocation,Repository Design,我希望获得用户输入位置x英里范围内的所有组织的列表。这将转换为长/横向位置 组织以long和lat存储在数据库中 我使用带有实体框架的MVC和带有respository模式的工作单元来访问数据集 这是我的真实陈述: public IQueryable<T> All { get { return dbSet; } } public IQueryable<T> A
public IQueryable<T> All
{
get
{
return dbSet;
}
}
public IQueryable<T> AllIncluding(params System.Linq.Expressions.Expression<Func<T, object>>[] includeProperties)
{
IQueryable<T> query = dbSet;
foreach (var includeProperty in includeProperties)
{
query = query.Include(includeProperty);
}
return query;
}
public IEnumerable<T> Where(System.Linq.Expressions.Expression<Func<T, bool>> predicate)
{
return dbSet.Where(predicate).AsEnumerable();
}
public IQueryable All
{
得到
{
返回dbSet;
}
}
公共可查询全部包含(params System.Linq.Expressions.Expression[]includeProperties)
{
IQueryable query=dbSet;
foreach(includeProperty中的var includeProperty)
{
query=query.Include(includeProperty);
}
返回查询;
}
公共IEnumerable,其中(System.Linq.Expressions.Expression谓词)
{
返回dbSet.Where(谓词).AsEnumerable();
}
为了查询datacontext中的数据,我为每个实体使用一个服务类,将UOW注入到每个服务中。各机构的服务电话如下:
public class OrgService :IOrgService
{
private IUnitOfWork _UoW;
public OrgService(IUnitOfWork UoW)
{
_UoW = UoW;
}
public Organisation GetOrgByID(int OrgID)
{
return _UoW.OrganisationRepo.Find(OrgID);
}
public IList<Organisation> GetAllOrgs()
{
return _UoW.OrganisationRepo.All.ToList();
}
public IList<Organisation> GetOrgsByLocation(double lat, double lng, int range)
{
/// I need to return a list of all organisations within X miles
}
}
公共类OrgService:IOrgService
{
私人工程;
公共组织服务(IUnitOfWork UoW)
{
_UoW=UoW;
}
公共组织GetOrgByID(int OrgID)
{
返回(组织)报告查找(OrgID);;
}
公共IList GetAllOrgs()
{
return _UoW.organizationrepo.All.ToList();
}
公共IList GetOrgsByLocation(双lat、双lng、整数范围)
{
///我需要返回X英里内所有组织的列表
}
}
所有其他查询都按照它们应该的方式工作,但是我不尝试编写GetOrgsByLocation()方法。这是我认为我需要得到结果的查询:
var userLocation = new GeoCoordinate(lat, lng);
var result = _UoW.OrganisationRepo.Where(x => new GeoCoordinate(x.Latitude, x.Longitude))
.Where(x => x.GetDistanceTo(userLocation) < radius).ToList();
var userLocation=新地理坐标(纬度、液化天然气);
var结果=_UoW.OrganizationRepo.Where(x=>新地理坐标(x.纬度,x.经度))
.Where(x=>x.GetDistanceTo(userLocation)
当我尝试运行此查询时,我得到:
“无法将system.device.location.geoCoordinate类型隐式转换为bool”
有人能帮忙吗
**更新-工作解决方案**
var userLocation = new GeoCoordinate(lat, lng);
var nearbyOrganizations = _UoW.OrganisationRepo.All.ToList()
.Select(x => new
{ //use an anonymous type or any type you want
Org = x,
Distance = new GeoCoordinate(x.Latitude, x.Longitude).GetDistanceTo(userLocation)
})
.Where(x => x.Distance < 50000)
.ToList();
foreach (var organisation in nearbyOrganizations)
{
Console.WriteLine("{0} ({1:n0} meters)", organisation.Org, organisation.Distance);
}
var userLocation=新地理坐标(纬度、液化天然气);
var nearbyOrganizations=\u UoW.organizationrepo.All.ToList()
.选择(x=>new
{//使用匿名类型或任何您想要的类型
Org=x,
距离=新地理坐标(x.纬度,x.经度)。GetDistanceTo(用户位置)
})
.式中(x=>x.距离<50000)
.ToList();
foreach(nearbyOrganizations中的var组织)
{
Console.WriteLine({0}({1:n0}米)”,organization.Org,organization.Distance);
}
感谢下面对该解决方案的帮助,虽然似乎所有对象都必须在orfer中查询才能正常工作,但似乎查询更适合在数据库上运行,我将不得不对此进行更多研究。Where方法必须返回布尔值
_UoW.OrganisationRepo.Where(x => new GeoCoordinate(x.Latitude, x.Longitude))
也许你想使用。在那里选择?下面的代码可以工作吗
_UoW.OrganisationRepo.Select(x => new GeoCoordinate(x.Latitude, x.Longitude))
.Where(x => x.GetDistanceTo(userLocation) < radius).ToList();
请注意,您选择的是布尔列表,因为您选择的是结果,而不是按结果过滤。你不知道哪些组织在半径范围内。这就是为什么我们分别使用.Select和.Where
试着这样做:
_UoW.OrganisationRepo.All
.Select(x => new GeoCoordinate(x.Latitude, x.Longitude))
.ToEnumerable() //or .ToList() or .ToArray(), make sure it's outside of EF's reach (prevent SQL generation for this)
.Where(x=> x.GetDistanceTo(userLocation) < radius).ToList()
\u UoW.organizationrepo.All
.选择(x=>新地理坐标(x.纬度,x.经度))
.ToEnumerable()//或.ToList()或.ToArray(),确保它不在EF的范围内(防止为此生成SQL)
.Where(x=>x.GetDistanceTo(userLocation)
但是,如果您想知道哪些组织位于半径范围内,则需要在路径上携带更多信息
var nearbyOrganizations = _UoW.OrganisationRepo.All.ToList()
.Select(x => new
{ //use an anonymous type or any type you want
Org = x,
Distance = new GeoCoordinate(x.Latitude, x.Longitude).GetDistanceTo(userLocation)
}) //it's probably outside EF's SQL generation step by now, but you could add one more .Select here that does the math if it fails (return the GeoCoordinate object)
.Where(x=> x.Distance < radius)
.ToList();
var nearbyOrganizations=\u UoW.organizationrepo.All.ToList()
.选择(x=>new
{//使用匿名类型或任何您想要的类型
Org=x,
距离=新地理坐标(x.纬度,x.经度)。GetDistanceTo(用户位置)
})//现在可能超出了EF的SQL生成步骤,但您可以再添加一个。如果失败,请选择此处进行计算(返回GeoCoordinate对象)
.式中(x=>x.距离<半径)
.ToList();
似乎了解更多有关.Where和.Select的信息对您很有用。它们非常有用。其中基本上是一个过滤器,并且。选择变换对象。由于匿名类型,你可以做任何你想做的事情
请注意,这将从数据库中获取所有对象。您可能希望使用数据库的本机功能处理地理数据,EF可能支持它。其中的方法必须返回布尔值
_UoW.OrganisationRepo.Where(x => new GeoCoordinate(x.Latitude, x.Longitude))
也许你想使用。在那里选择?下面的代码可以工作吗
_UoW.OrganisationRepo.Select(x => new GeoCoordinate(x.Latitude, x.Longitude))
.Where(x => x.GetDistanceTo(userLocation) < radius).ToList();
请注意,您选择的是布尔列表,因为您选择的是结果,而不是按结果过滤。你不知道哪些组织在半径范围内。这就是为什么我们分别使用.Select和.Where
试着这样做:
_UoW.OrganisationRepo.All
.Select(x => new GeoCoordinate(x.Latitude, x.Longitude))
.ToEnumerable() //or .ToList() or .ToArray(), make sure it's outside of EF's reach (prevent SQL generation for this)
.Where(x=> x.GetDistanceTo(userLocation) < radius).ToList()
\u UoW.organizationrepo.All
.选择(x=>新地理坐标(x.纬度,x.经度))
.ToEnumerable()//或.ToList()或.ToArray(),确保它不在EF的范围内(防止为此生成SQL)
.Where(x=>x.GetDistanceTo(userLocation)
但是,如果您想知道哪些组织位于半径范围内,则需要在路径上携带更多信息
var nearbyOrganizations = _UoW.OrganisationRepo.All.ToList()
.Select(x => new
{ //use an anonymous type or any type you want
Org = x,
Distance = new GeoCoordinate(x.Latitude, x.Longitude).GetDistanceTo(userLocation)
}) //it's probably outside EF's SQL generation step by now, but you could add one more .Select here that does the math if it fails (return the GeoCoordinate object)
.Where(x=> x.Distance < radius)
.ToList();
var nearbyOrganizations=\u UoW.organizationrepo.All.ToList()
.选择(x=>new
{//使用匿名类型或任何您想要的类型
Org=x,
距离=新地理坐标(x.纬度,x.经度)。GetDistanceTo(用户位置)
})//现在可能已经超出了EF的SQL生成范围,但您可以