5

我使用的數據庫首先與實體框架5.我們有兩個表(大型簡體):如何更改導航屬性名稱轉換爲有意義的名字

  • 地址
    • 鎮(等。)
  • 客戶
    • 名稱
    • BillingAddress
    • 是DeliveryAddress
    • AltDeliveryAddress

當我們使用Visual Studio數據庫導入到EF( 「從數據庫更新模式」),我們最終得到這樣的代碼:

Customer myCustomer; 
var a = myCustomer.Address; 
var b = myCustomer.Address1; 
var c = myCustomer.Address2; 

我明顯想要的是這樣的:

var a = myCustomer.BillingAddress; 
var z = myCustomer.BillingAddress.Street; // etc. 

我可以在設計器中編輯模型,改變導航屬性給我正確的名字。然而,這不是一個可行的解決方案,因爲我們每次修改數據庫時都會重建模型。我試圖創造這樣一個分部類

一個選項(從現有MyModel.Designer.cs複製只屬性名稱代碼更改):

public partial class Customer : EntityObject 
{ 
    [EdmRelationshipNavigationPropertyAttribute("MyModel", "FK_Customers_Addresses_BillingAddress", "Address")] 
    public Address BillingAddress 
    { 
     get { 
      return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<LookupItem>("MyModel.FK_Customers_Addresses_BillingAddress", "Address").Value; 
     } 
     set { 
      ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<LookupItem>("MyModel.FK_Customers_Addresses_BillingAddress", "Address").Value = value; 
     } 
    } 
} 

然而,當我運行它,我得到以下錯誤:

The number of members in the conceptual type 'MyModel.Customer' does not match with the number of members on the object side type 'MyNamespace.DataModel.Customer'. Make sure the number of members are the same.

我使用[NotMapped()]屬性試過了,但是這並沒有什麼不同。如果我刪除[EdmRelationshipNavigationPropertyAttribute ...]屬性然後LINQ的,錯誤如下抱怨:

The specified type member 'BillingAddress' is not supported in LINQ to Entities. Only initializers, entity members, and entity navigation properties are supported.

是否有任何其他的方式來實現有意義的名稱在客戶對象?

這裏就是我想在最後:

var j = myCustomer.BillingAddress; 
var k = myCustomer.BillingAddress.Street; 
var l = myCustomer.BillingAddress.Town; // etc. 

回答

2

您可以將屬性添加到您的局部類,這將是存取器性能Address1Address2

例子:

public partial class Customer : EntityObject 
{ 
    public Address BillingAddress 
    { 
     get 
     { 
      return this.Address; 
     } 
     set 
     { 
       this.Address = value; 
     } 
    } 
} 

更新:它不會使用LINQ工作的實體。這恐怕是數據庫第一種方法的侷限。這是我們使用EF Code First的原因之一。在代碼中,您可以完全控制實體映射。(代碼第一意味着在代碼中映射,這並不意味着如果你不需要它,你的數據庫將從這個代碼生成)。

+0

如果可以確定EF生成的名稱與真實數據庫名稱之間的映射,那麼這起作用。 即,如果.Address2總是AltDeliveryAddress那麼沒關係,但它看起來不是很安全。 – andrewpm

+0

實際上,當我嘗試在LINQ中使用它時,這不起作用。 這是我的代碼: var customersInSeattle = cs.Where(c => c.DeliveryAddress.Town ==「Seattle」); 我收到此錯誤: LINQ to Entities不支持指定的類型成員'DeliveryAddress'。僅支持初始化程序,實體成員和實體導航屬性。 – andrewpm

+0

是的,這是真的......恐怕這是數據庫第一種方法的侷限性。這是我們使用EF Code First的原因之一。在代碼中,您可以完全控制實體映射。 (代碼第一意味着在代碼中映射,這並不意味着如果你不需要它,你的數據庫將從這個代碼生成)。 –

3

你可能不必擔心這個問題。在模型設計器中更改屬性名稱後,EF會記住自定義命名。它不會被後續更新覆蓋。

+2

只要您不移除實體並將其讀取到模型中,只有在您想將模型與數據庫同步時纔會發生。 F.E.刪除數據庫中的列在刷新時不會在模型中執行相同的操作 – KroaX

+2

不幸的是,EF設計人員並不可靠。通常我們只是刪除整個模型並重新創建它,因爲嘗試更新會破壞它。因此這個選項對我們不可用。 – andrewpm

+0

如果我對模型進行了更改,它是否也會對現有的數據庫和代碼類進行相應的更改? ...我真的很想。 –

0

我知道這有點舊,但似乎處理這種情況的最簡單/最好的方法是利用EF5電動工具「首先反向工程代碼」。

http://msdn.microsoft.com/en-us/data/jj200620

它給你的代碼首先映射所有優點與數據庫第一對象創建的簡單/便捷。

0

有這裏描述的解決方案:

Improve navigation property names when reverse engineering a database

可以包括代碼生成模板到您的項目(* TT文件)。按鏈接描述修改它們。示例在這裏:https://github.com/markuspeter/EFPowerToolsTemplates(檢查分支的更改)

然後您的命名可以生成更好的名稱。

+1

總是建議從鏈接資源中包含代碼片段/最合適的一段或兩段,即使僅用於防止鏈接腐爛。 – bardzusny