2014-05-10 31 views
1

我有一個Odata服務,它公開EF6代碼的第一個模型。其中一些實體包括DbGeography字段。儘管DbGeography字段有一個相當醜陋的序列化格式,但我無法弄清楚如何將POST或PUT實體添加到服務中,我可以獲取這些字段。 DbGeography類型似乎與反序列化相沖突。OData + EF。寫地理類型

任何人都可以提供一個例子或鏈接如何做到這一點?

+1

真的很煩人,這還沒有被MS修復。 – Tim

回答

2

我也有過這個問題。它顯然是一個bug。

這裏有兩種選擇 - 下降到舊的System.Data.Entity.DbGeography(而不是System.Data.Entity.Spatial.DbGeography)的EF5,或者等到他們補丁。

編輯:它是一個漫長的時間,也是迄今爲止唯一的黑客,我想出了是這樣的一種方式來寫的屬性和遮醜的序列化格式(但是仍然不能查詢反對

private bool hasSetLongitude = false; 
    private bool hasSetLatitiude = false; 
    private double? longitude = null; 
    private double? latitiude = null; 

    /// <summary> 
    /// Get or set the coordinates. 
    /// </summary> 
    [Column("engi_coord"), Required] 
    public DbGeography Coordinates { get; set; } 

    /// <summary> 
    /// Get or set the lang coordinates. 
    /// </summary> 
    [Column("engi_lng"), DatabaseGenerated(DatabaseGeneratedOption.Computed)] 
    public double? Longitude 
    { 
     get 
     { 
      return this.Coordinates != null ? this.Coordinates.Longitude : (double?)null; 
     } 
     set 
     { 
      this.longitude = value; 
      this.hasSetLongitude = true; 
      if (this.hasSetLongitude) 
      { 
       if (this.longitude.HasValue && 
        this.latitiude.HasValue) 
       { 
        this.Coordinates = DbGeography.PointFromText(string.Format("POINT({0} {1})", this.longitude.Value, this.latitiude.Value), 4326); 
       } 
       else 
       { 
        this.Coordinates = null; 
       } 
      } 
     } 
    } 

    /// <summary> 
    /// Get or set the lat coordinates. 
    /// </summary> 
    [Column("engi_lat"), DatabaseGenerated(DatabaseGeneratedOption.Computed)] 
    public double? Latitude 
    { 
     get 
     { 
      return this.Coordinates != null ? this.Coordinates.Latitude : (double?)null; 
     } 
     set 
     { 
      this.latitiude = value; 
      this.hasSetLatitiude = true; 
      if (this.hasSetLatitiude) 
      { 
       if (this.longitude.HasValue && 
        this.latitiude.HasValue) 
       { 
        this.Coordinates = DbGeography.PointFromText(string.Format("POINT({0} {1})", this.longitude.Value, this.latitiude.Value), 4326); 
       } 
       else 
       { 
        this.Coordinates = null; 
       } 
      } 
     } 
    } 

遷移到添加計算列:

 this.Sql("ALTER TABLE dbo.engi_engineer ADD engi_lng AS engi_coord.Long"); 
     this.Sql("ALTER TABLE dbo.engi_engineer ADD engi_lat AS engi_coord.Lat"); 

現在忽略API座標屬性:

 this.EntityType.Ignore(p => p.Coordinates); 
+0

謝謝你。我最終通過向我的實體添加一個字符串類型的屬性來完成一些令人討厭的解決方法,該屬性可用於獲取/設置WKT。你有沒有鏈接到任何你被告知這是一個錯誤? – Barguast

+0

@Barguast:http://blogs.msdn.com/b/webdev/archive/2014/03/13/getting-started-with-asp-net-web-api-2-2-for-odata-v4- 0.aspx?PageIndex = 3 – Tim

+0

** Quote **:在本文中,我們可以發現'System.Data.Entity.Spatial.DbGeography'是'Edm.Geography'的'ClrEquivalentType'。它還提到EF.Utility.CS.ttinclude將在內部使用來自'System.Data.Metedata.Edm'命名空間的類。所以根據文章和測試結果,我認爲這是一個EF在內部不會將'System.Data.Entity.Spatial.DbGeography'轉換爲'Edm.Geography'的錯誤。 – Tim

0

現在已經過去了一年多了,而且看起來這種情況不久就會得到修復。特別是EF7即將推出。

所以,我想以另一種方式來解決這個問題。
如果DbGeography類型未作爲類中的屬性公開,而是顯示未映射的緯度和經度屬性,然後在其GET/SET上我們更新隱藏的DbGeography屬性,該怎麼辦?

我已經試過這個,但是EF一直不成功。
你可以做的是在POST/PUT控制器中調用是使用存儲過程還是SQL文本來更新數據。

如果我發現如何讓這個與EF一起工作,我會在這裏發佈。