【问题标题】:Quoted Identifier - EF Code First引用标识符 - EF 代码优先
【发布时间】:2018-02-28 19:30:49
【问题描述】:

EF 6 中是否有任何选项可以在 Oracle 中使用非引号标识符创建表?

背景:

我们首先使用的是 EF 代码。到现在为止产品应该支持SQL Server,现在Oracle是通过PO添加的。对于大部分功能,我们使用带有 LINQ 的 EF 模型来填充数据,但对于少数特殊功能,我们编写了生成 sql 查询的引擎。

示例: 从 Tab1 中选择 Col1、Col2、Col3

所以上面生成的查询适用于 SQL Server 数据库,因为 EF 在 SQL Server 中生成了带有非引号标识符的表。

但是相同的查询在 Oracle 中不起作用,因为 EF 生成了所有带有引号标识符的表。因此,要成功执行上述查询,引擎必须生成:

从“Tab1”中选择“Col1”、“Col2”、“Col3”

我想避免更改查询引擎。

那么,EF 6 中是否有任何选项可以在 Oracle 中使用非引号标识符创建表?

非常感谢...

【问题讨论】:

    标签: c# sql-server oracle entity-framework oracle11g


    【解决方案1】:

    这里的诀窍是你不需要禁止引用标识符,你只需要将所有标识符强制全部大写。在 Oracle 中,未引用的标识符将转换为目录中的所有大写字母。然后在解析 SQL 时,Oracle 将 SQL 中不带引号的标识符转换为全部大写以匹配目录中的标识符。

    这就是 Oracle 创建不区分大小写目录的假象的方式。

    您可以使用属性、Fluent API 或自定义约定强制您的实体和属性映射到全大写数据库标识符。

    这里有一个关于如何使用自定义约定将 Oracle 表和列标识符规范化为全大写和下划线的想法(假设它们的实体属性和 CLR 类型名称是 PascalCase)。

    namespace OracleConventions
    {
        using System.Data.Entity.Core.Metadata.Edm;
        using System.Data.Entity.Infrastructure;
        using System.Data.Entity.Infrastructure.Pluralization;
        using System.Data.Entity.ModelConfiguration.Conventions;
        using System.Text.RegularExpressions;
    
        static class Identifiers
        {
            public static string CreateIdentifier(string entityName)
            {
                var result = Regex.Replace(entityName, "[a-z][A-Z]", m => m.Value[0] + "_" + m.Value[1]);
    
                return result.ToUpper();
            }
        }
    
        public class AllCapsTableAndColumnConvention : System.Data.Entity.ModelConfiguration.Conventions.Convention
        {
    
            public AllCapsTableAndColumnConvention()
            {
                var ps = (IPluralizationService)DbConfiguration.DependencyResolver.GetService(typeof(IPluralizationService), null);
    
                this.Types().Configure(t => t.ToTable(Identifiers.CreateIdentifier(ps.Pluralize(t.ClrType.Name))));
                this.Properties().Configure(p => p.HasColumnName(Identifiers.CreateIdentifier(p.ClrPropertyInfo.Name)));           
    
            }
        }
        public class AllCapsForeignKeyConvention : IStoreModelConvention<AssociationType>
        {
    
            public void Apply(AssociationType association, DbModel model)
            {
                // Identify ForeignKey properties (including IAs)  
                if (association.IsForeignKey)
                {
                    // rename FK columns  
                    var constraint = association.Constraint;
                    foreach (var p in constraint.FromProperties.Union(constraint.ToProperties))
                    {
                        p.Name = Identifiers.CreateIdentifier(p.Name);
                    }
    
                }
            }
    
        }
    
    }
    

    然后您将在 OnModelCreating 中注册约定

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Conventions.Add(new OracleConventions.AllCapsTableAndColumnConvention());
        modelBuilder.Conventions.Add(new OracleConventions.AllCapsForeignKeyConvention());
        base.OnModelCreating(modelBuilder);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多