在Web API 2项目中,使用EF,我试图让控制器返回数据库中的项目列表。那很简单。 当我希望它根据位置列表返回从下面的函数计算的单个坐标值时,问题就来了。 所有方法都是基于GeoLocation值列表计算中心点。该方法按预期工作。什么不起作用,是控制器动作。
运行以下代码,结果为
'LINQ to Entities没有 识别方法'Double ToDouble(System.String)'方法,和 此方法无法转换为商店表达式。'
我目前正在使用item.Locations.FirstOrDefault().cX
,我
知道将无法工作,因为它将始终返回相同的值。但
item.cX
不起作用。那么我该怎么用才能做出我的陈述
按计划工作?
代码
IdentityModel:
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);
}
答案 0 :(得分:1)
尝试这样的事情:
public IQueryable<GeoCoordinate> GetList()
{
// this ToList fetches the data from the db.
// now you don't have to worry about convert inside EF
var sourceItems = db.Items.Include(x => x.Locations).ToList();
// Select updated to answer part 2 (I believe).
var items = sourceItems.Select(item => new ItemDTO()
{
Id = item.Id,
Title = item.Title
Coordinates = item.Locations
.Select(itemLocation => new GeoCoordinate()
{
Latitude = Convert.ToDouble(itemLocation.cX),
Longitude = Convert.ToDouble(itemLocation.cY)
})
})
.AsEnumerable()
.Select(fetchedItem => GetCentralGeoCoordinate(fetchedItem.Coordinates));
return items.AsQueryable();
}