如何将导航属性名称更改为有意义的名称

时间:2012-11-23 12:14:02

标签: c# entity-framework entity-framework-5 ef-database-first

我正在使用Database First和Entity Framework 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;
        }
    }
}

但是当我运行它时,我收到以下错误:

  

概念类型“MyModel.Customer”中的成员数与对象端类型“MyNamespace.DataModel.Customer”上的成员数不匹配。确保成员数量相同。

我尝试过使用[NotMapped()]属性,但这没有任何区别。如果我删除[EdmRelationshipNavigationPropertyAttribute ...]属性,那么Linq会抱怨以下错误:

  

LINQ to Entities不支持指定的类型成员'BillingAddress'。仅支持初始化程序,实体成员和实体导航属性。

还有其他方法可以在Customers对象中实现有意义的名称吗?

这就是我最终想要的东西:

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

4 个答案:

答案 0 :(得分:4)

您可能不必担心这一点。在模型设计器中更改属性名称后,EF将记住自定义命名。它不会被后续更新覆盖。

答案 1 :(得分:2)

您可以向属于Address1Address2等属性的访问者的部分​​类添加属性。

示例:

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

更新:它不适用于linq实体。 我担心这是数据库第一种方法的局限性。这是我们使用EF Code First的原因之一。在Code First中,您可以完全控制实体映射。 (代码优先意味着在代码中进行映射,这并不意味着如果您不想要它,将从此代码生成您的数据库。)

答案 2 :(得分:0)

我知道这有点旧,但似乎处理这种情况的最简单/最好的方法是利用EF5电源工具“首先进行逆向工程代码”。

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

它为您提供了代码优先映射的所有优点,以及数据库第一个对象创建的简单性和便利性。

答案 3 :(得分:0)

这里有一个解决方案:

Improve navigation property names when reverse engineering a database

您可以将代码生成模板(* .tt文件)包含到项目中。按照链接中的描述修改它们。示例在这里:https://github.com/markuspeter/EFPowerToolsTemplates(检查更改分支)

然后可以使用更好的名称生成命名。