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

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

我正在研究用 Entity Framework 4 替换或补充我们自己开发的 ORM 系统,我注意到后者最终可能会导致我们定义为编程代码的命名约定和我们的数据库。作为一家微软商店,我们基本上决定关注 Microsoft's naming guidelines for our code ,表示对成员、命名空间等使用 Pascal 大小写;避免使用下划线等。

毫无疑问,EF4 中的默认实体命名约定非常适用于这些标准。例如,一个名为 SalesOrder 的实体将生成一个名为 SalesOrder 的类和一个名为 SalesOrders 的实体集。默认情况下,EF4 模型优先设计将生成与实体集同名的表(在本示例中,生成的表名为 SalesOrders)。但是,我们的数据库标准建议在单词之间使用所有小写字母和下划线(例如,sales_orders)。因此,“按原样”使用 Entity Framework 将导致我们开始偏离它们。

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

更新:

我在下面尝试 Ladislav 的解决方案,但我似乎无法在 Entity Framework 模型设计器中获得 Generate Database from Model 选项来识别我的自定义实用程序。我在文件夹中有一个名为 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 生成代码中吗?

最终解决方案:

在我意识到我没有将 C# 代码包装在我的 MyOrg.EF.Utility.CS.ttinclude 文件中之后,我终于能够使用这个:

<#+
[my code]
#>

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

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

最佳答案

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

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

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

关于entity-framework - 解决 EF4 中的实体与我们的数据库标准之间的命名约定冲突?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6680957/

相关文章:

c# - 使用数据库优先方法排除表

c# - 如何使用 try-catch block 连接到 Entity Framework ?

.net - 使用具有模型优先方法的 EF4 迁移工具

asp.net - 究竟什么是 "Context"命名约定

c# - 如何设置字符串属性 C# EF 的分隔词的最大长度

c# - 如何设置ID对应 Entity Framework 中的对象

Java:创建 "System"类是一件坏事吗?

php - mysql命名约定

entity-framework - EF 4.1 CF : CREATE DATABASE permission denied in database 'master'

c# - 使用 EntityFramework : Context per Presenter or long conversation pattern for Windows Forms Applications?