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

Der*_*rek 3 entity-framework naming-conventions entity-framework-4

我正在研究用Entity Framework 4替代或补充我们的本地ORM系统,并且我注意到后者可能最终导致我们定义为编程代码和数据库的命名约定之间的冲突。作为Microsoft商店,我们在很大程度上决定遵循Microsoft的代码命名准则,即对成员,名称空间等使用Pascal大小写;避免使用下划线等。

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

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

更新:

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

%VSINSTALLDIR%\Common7\IDE\Extensions\Microsoft\Entity Framework Tools\Templates\Includes
Run Code Online (Sandbox Code Playgroud)

基本上看起来像这样:

<#@ 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;
    }

}
Run Code Online (Sandbox Code Playgroud)

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

<#@ include file="MyOrg.EF.Utility.CS.ttinclude"#>
Run Code Online (Sandbox Code Playgroud)

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

string tableName = CustomUtilities.EntityNameToSqlName(Id(entitySet.GetTableName()));
Run Code Online (Sandbox Code Playgroud)

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

最终解决方案:

在意识到我没有将C#代码包装在MyOrg.EF.Utility.CS.ttinclude文件中后,我终于能够完成此工作:

<#+
[my code]
#>
Run Code Online (Sandbox Code Playgroud)

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

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

Geo*_*ker 5

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

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

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