【发布时间】:2018-04-24 02:44:01
【问题描述】:
在使用 EF 的 Web API 2 项目中,我试图让控制器返回数据库中的项目列表。就这么简单。 问题来了,当我希望它返回一个单一的坐标值时,该坐标值是根据下面的一个函数计算的,基于位置列表。 该方法所做的所有事情都是根据 GeoLocation 值列表计算中心点。该方法按预期工作。什么不起作用,是控制器动作。
-
运行下面的代码,结果是
'LINQ to Entities 没有 识别方法 'Double ToDouble(System.String)' 方法,以及 此方法无法转换为商店表达式。'
我目前正在使用
item.Locations.FirstOrDefault().cX,我 知道不会起作用,因为它总是会返回相同的值。但item.cX不起作用。那么我应该用什么来发表我的声明 按预期工作?
代码
身份模型:
public System.Data.Entity.DbSet<myModel.Item> Items { get; set; }
型号:
public class Item
{
public int Id { get; set; }
public string Title { get; set; }
public virtual ICollection<Location> Locations { get; set; }
}
public class ItemDTO
{
public int Id { get; set; }
public string Title { get; set; }
public IEnumerable<GeoCoordinate> Coordinates { get; set; }
}
public class Location
{
public int Id { get; set; }
public string cX { get; set; }
public string cY { get; set; }
public virtual Item Item { get; set; }
}
控制器:
[EnableQuery()]
public IQueryable<GeoCoordinate> GetList()
{
var items = db.Items
.Select(item => new ItemDTO()
{
Id = item.Id,
Title = item.Title
Coordinates = item.Locations
.Select(LocationsItem => new GeoCoordinate() //System.Device.Location
{
Latitude = Convert.ToDouble(item.Locations.FirstOrDefault().cX),
Longitude = Convert.ToDouble(item.Locations.FirstOrDefault().cY)
})
.ToList()
})
.AsEnumerable()
.Select(fetchedItem => GetCentralGeoCoordinate(fetchedItem.Coordinates));
return items.AsQueryable();
}
GetCentralGeoCoordinate 函数:
public static GeoCoordinate GetCentralGeoCoordinate(IEnumerable<GeoCoordinate> geoCoordinates)
{
if (geoCoordinates.Count() == 1)
{
return geoCoordinates.Single();
}
double x = 0;
double y = 0;
double z = 0;
foreach (var geoCoordinate in geoCoordinates)
{
var latitude = geoCoordinate.Latitude * Math.PI / 180;
var longitude = geoCoordinate.Longitude * Math.PI / 180;
x += Math.Cos(latitude) * Math.Cos(longitude);
y += Math.Cos(latitude) * Math.Sin(longitude);
z += Math.Sin(latitude);
}
var total = geoCoordinates.Count();
x = x / total;
y = y / total;
z = z / total;
var centralLongitude = Math.Atan2(y, x);
var centralSquareRoot = Math.Sqrt(x * x + y * y);
var centralLatitude = Math.Atan2(z, centralSquareRoot);
return new GeoCoordinate(centralLatitude * 180 / Math.PI, centralLongitude * 180 / Math.PI);
}
【问题讨论】:
-
你试过用 double.Parse(item.Locations.FirstOrDefault().cX) 代替 Convert.Double(item.Locations.FirstOrDefault().cX) 吗?
-
ToDouble 无法转换为 SQL - EF 将尝试将整个 IQueryable 部分转换为一个 SQL 查询;它失败了,因为在 SQL 中无法进行转换。你必须使用 db.Items.ToList()... 来完成这个任务。
-
@ChrisBartlett 是的,结果相同。
-
@DevilSuichiro 我知道它不会像现在这样工作 - 但我不确定如何修改我的代码以使其工作 - 因此我的问题:-)
标签: c# entity-framework linq asp.net-web-api asp.net-web-api2