自定义EF6“代码优先从数据库”代码生成,以获得更有意义的导航属性名称

时间:2017-10-25 18:58:06

标签: c# sql-server entity-framework-6 code-generation navigation-properties

我有一个基于SQL Server的ASP.NET MVC 5应用程序,我正在使用Entity Framework 6与数据库通信。

我们正在使用“混合”方法 - 我们使用经典SQL脚本管理所有数据库结构,我们将其部署到数据库服务器上,然后从该SQL Server数据库生成“代码优先”类。在大多数情况下,这种方法运作得相当好。

有一件事让我感到困惑的是,如果一个给定的表有多个FK链接到另一个表,EF6代码生成使用的命名约定非常蹩脚....

假设我有一个表(因此实体)Site代表某处的某个站点,并且该站点有三个指向Contact表的链接,用于表示各种角色 - “主要”联系人,“支持“联系和”销售“联系。所以我在SQL Server中的表看起来像这样:

CREATE TABLE dbo.Site
(
    SiteID INT NOT NULL
        CONSTRAINT PK_Site PRIMARY KEY CLUSTERED,
    .... some other properties, of no interest or relevance here .....
    MainContactId INT NOT NULL
        CONSTRAINT FK_Site_MainContact FOREIGN KEY REFERENCES dbo.Contact(ContactId),
    SalesContactId INT NOT NULL
        CONSTRAINT FK_Site_SalesContact FOREIGN KEY REFERENCES dbo.Contact(ContactId),
    SupportContactId INT NOT NULL
        CONSTRAINT FK_Site_SupportContact FOREIGN KEY REFERENCES dbo.Contact(ContactId)
)

我一直希望现有数据库生成的EF6代码首先足够聪明,可以读取这些列名,并为实体上的导航属性提供有意义的名称 - 但是,这就是我得到的:

 [Table("Site")]
 public partial class Site
 {
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public int SiteID { get; set; }

    public int MainContactId { get; set; }
    public int SalesContactId { get; set; }
    public int SupportContactId { get; set; }

    public virtual Contact Contact { get; set; }        
    public virtual Contact Contact1 { get; set; }
    public virtual Contact Contact2 { get; set; }
}

虽然实际的FK列是正常的 - “推断的”导航属性很糟糕 - ContactContact1Contact2 - 严重的,这是最好的命名???我认为不是......我会非常喜欢来称它们为“MainContact”,“SalesContact”,“SupportContact” - 这会不会更有意义?为了以后的使用会更清楚吗?

我安装了自定义T4模板(Nuget包“EntityFramework.CodeTemplates.CSharp”),我发现有一些有趣且可能非常有用的辅助类正在使用(CSharpCodeHelperEdmHelper来自EntitySetDbModel命名空间的Microsoft.Data.Entity.DesignSystem.Data.Entity.Infrastructure - 不幸的是,大多数都是稀疏文档,而且它们的构造函数通常都是内部的 - 所以我无法构建我自己的工具基于那些现成的类。

还有其他方法吗?我真的很想教代码生成一些智能 - 现在这只是达不到通常的标准,并要求我对生成的文件进行大量的手动更改 - 徒劳无功,每次冲洗数字马桶我需要从数据库中重新生成类......

0 个答案:

没有答案