2017-11-11 112 views
1

在Web API 2項目中,我試圖獲取屬於單個項目的所有座標(可以是1到1000之間的任意值)並計算中心點。 計算中心點的函數按預期工作。返回錯誤的類型 - cast?

但是下面的控制器失敗,錯誤:Cannot implicitly convert SYstem.Linq.IQueryable<System.Device.Location.GeoCoordinates> to System.Linq.IQueryable<ItemDTO>。在線return items.AsQueryable();

我怎樣才能得到它作爲ItemDTO返回?

模型

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; } 
} 

控制器

public IQueryable<ItemDTO> GetList() 
{ 
    var sourceItems = db.Items.Include(x => x.Locations).ToList(); 

    var items = sourceItems.Select(item => new ItemDTO() 
     { 
      Id = item.Id, 
      Title = item.Title 
      Coordinates = item.Locations 
       .Select(itemLocation => new GeoCoordinate() 
       { 
        Latitude = Double.Parse(itemLocation.cX, CultureInfo.InvariantCulture), 
        Longitude = Double.Parse(itemLocation.cY, CultureInfo.InvariantCulture) 
       }) 
     }) 
     .AsEnumerable() 
     .Select(fetchedItem => GetCentralGeoCoordinate(fetchedItem.Coordinates)); 

    return items.AsQueryable(); 
} 

方法

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

你的錯誤是因爲該行的:'。選擇(fetchedItem => GetCentralGeoCoordinate(fetchedItem.Coordinates));'在結束您嘗試使用「選擇」方法選擇「GeoCoordinate」 –

回答

0

按照簽名的方法,IQueryable<ItemDTO> GetList()應返回IQueryable<ItemDTO>類型的值,則該方法GetCentralGeoCoordinate應該返回一個值爲GeoCoordinate

現在看看進GetList()方法中,在這樣的:查詢選擇

.Select(fetchedItem => GetCentralGeoCoordinate(fetchedItem.Coordinates)); 

,這意味着在所選擇的代碼的每個項目是GeoCoordinate類型的並因此items.AsQueryable()會給你IQueryable<GeoCoordinate>。這不等同或可轉換爲IQueryable<ItemDTO>並導致問題。

Either you have to change the signature of GetList to IQueryable<GeoCoordinate> or need to create a method to get the IQueryable<ItemDTO> from fetchedItem to solve the issue.

您可以用下面的代碼試試:

public IQueryable<ItemDTO> GetList() 
{ 
    var sourceItems = db.Items.Include(x => x.Locations).ToList(); 
    var items = sourceItems.Select(item => new ItemDTO() 
     { 
      Id = item.Id, 
      Title = item.Title 
      Coordinates = GetCentralGeoCoordinate(
          item.Locations 
           .Select(itemLocation => new GeoCoordinate() 
           { 
            Latitude = Double.Parse(itemLocation.cX, CultureInfo.InvariantCulture), 
            Longitude = Double.Parse(itemLocation.cY, CultureInfo.InvariantCulture) 
           }) 
          });  

    return items.AsQueryable(); 
} 
+0

感謝您回覆:-)解決方案的外觀如何?或者,我可以在其他地方使用GetCentralGeoCoordinate函數嗎?我希望輸出爲包含所有屬於該值的ItemDTO以及GetCentralGeoCoordinate返回的值 – brother

+0

@brother爲什麼不在此行中使用'GetCentralGeoCoordinate' Coordinates = item.Locations' –

+0

@brother:我已經在答案中做了一些更新,請回顧一下,讓我知道\ –