解决EF4中的实体与我们的数据库标准之间的命名约定冲突?

时间:2011-07-13 14:57:35

标签: entity-framework entity-framework-4 naming-conventions

我正在研究用实体框架4替换或补充我们自己开发的ORM系统,我注意到后者可能最终导致我们定义为编程代码的命名约定和数据库。作为一家微软商店,我们在很大程度上决定遵循Microsoft's naming guidelines for our code,即使用Pascal套管作为成员,名称空间等;避免使用下划线,等等。

EF4中的默认实体命名约定毫不奇怪,适用于这些标准。例如,名为 SalesOrder 的实体将生成名为 SalesOrder 的类和名为 SalesOrders 的实体集。默认情况下,EF4 Model-First设计将生成与实体集同名的表(在此示例中,生成的表名称为SalesOrders)。但是,我们的数据库标准建议在单词之间使用所有小写和下划线(例如, sales_orders )。因此,“按原样”使用实体框架将导致我们开始偏离它们。

实体框架中是否有任何地方可以覆盖它的行为以使用实体集名称作为SQL表名称?我似乎找不到为生成的SQL脚本指定备用表名的明显位置。如果我们继续使用EF4,那么让我们重新考虑数据库命名约定是唯一合理的解决方案吗?

更新

我正在尝试下面的Ladislav解决方案,但我似乎无法在Entity Framework模型设计器中获得从模型生成数据库选项来识别我的自定义实用程序。我在文件夹中有一个名为 MyOrg.EF.Utility.CS.ttinclude 的文件:

%VSINSTALLDIR%\Common7\IDE\Extensions\Microsoft\Entity Framework Tools\Templates\Includes

它基本上是这样的:

<#@ import namespace="Microsoft.CSharp"#>
<#@ import namespace="System.Text"#>


public class CustomUtilities
{
    public static string EntityNameToSqlName(string name)
    {
        string sqlName = "";    // The table name based on the input model name
        string pattern = "([A-Z]+[s])|([A-Z](?=[a-z]))|((?<=[a-z])[A-Z])";  //Pattern for the regex exp. below

        // Separate out each word with spaces:
        sqlName = System.Text.RegularExpressions.Regex.Replace(name, pattern, " $&");

        // Replace spaces with underscores and then make lowercase:
        sqlName = sqlName.Trim().Replace(" ", "_").ToLower();

        return sqlName;
    }

}

我试图在我的自定义.tt DDL生成文件中引用此文件,如下所示:

<#@ include file="MyOrg.EF.Utility.CS.ttinclude"#>

但是,如果我尝试在.tt文件中使用如下代码引用上述函数:

string tableName = CustomUtilities.EntityNameToSqlName(Id(entitySet.GetTableName()));

Visual Studio然后抱怨当前上下文中不存在名称'CustomUtilities'。从“CustomUtilities.EntityNameToSqlName”中删除类名会返回类似的错误。我应该尝试不同的方法将自定义函数插入DDL生成代码吗?

最终解决方案:

在我意识到我没有用我的 MyOrg.EF.Utility.CS.ttinclude 文件包装C#代码后,我终于得到了这个工作:

<#+
[my code]
#>

我还需要添加 GenerateTSQL.Utility 文件中的 WriteColumns()方法的公共副本,以便它使用我的EntityNametoSqlName()方法。< / p>

不幸的是,我原来的 SSDLToSQL10.tt 文件的自定义版本现在有点乱,因为我需要在很多项目中包装 CustomUtilities.EntityNameToSqlName()在那里。

3 个答案:

答案 0 :(得分:4)

正确的解决方案是更改数据库命名约定。

为什么尾巴摇尾巴?在现代编程中,大多数操作都发生在高度可扩展的业务/服务层,而不是数据库。程序员应该使用适用于两者的命名约定 - 它应该满足日复一日使用这些对象的应用程序开发人员的需求。在某些情况下,它可能应该满足前端开发人员的需求,而其他服务器端则需要。

命名约定的全部目的是降低复杂性。然而,这里公认的解决方案是实现各种额外的复杂性。而且每个其他ORM都必须为这个人为问题提出他们自己的复杂解决方案。

答案 1 :(得分:2)

当然有。有T4模板可以将模型转换为SQL DDL脚本。您可以复制此模板,并将自己的名称生成逻辑放入新副本中。之后,您只需在设计器中设置此模板(DDL生成模板属性)并运行从模型生成数据库...

您将在以下位置找到默认模板:

%VSINSTALLDIR%\Common7\IDE\Extensions\Microsoft\Entity Framework Tools\DBGen\SSDLToSQL10.tt

答案 2 :(得分:0)

你可以做到。您需要实现自定义模型构建器,以使用相关表和相关列映射实体。  您可以通过将此函数添加到上下文类来覆盖OnModelCreating函数来构建客户模型。

protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
     modelBuilder.Entity<EntityName>().Map(c => c.ToTable("TableName"));//to map entity with table
     modelBuilder.Entity<EntityName>().Property(s => s.Property).HasColumnName("ColomnName");//to map properties with colomns
}
相关问题