在EF 6中是否有任何选项可以在Oracle中创建带有非加引号标识符的表?
背景
我们一直在使用EF代码。直到现在产品应该支持SQL Server,现在Oracle由PO添加。对于大多数功能,我们使用带有LINQ的EF模型来填充数据,但是由于很少有特殊功能,我们编写了生成sql查询的引擎。
示例: 从Tab1中选择Col1,Col2,Col3
因此,上面生成的查询与SQL Server数据库一起工作正常,因为EF在SQL Server中生成了带有非引号标识符的表。
但同样的查询在Oracle中不起作用,因为EF生成了带引号标识符的所有表。因此,要成功执行上述查询,引擎必须生成:
选择" Col1"," Col2"," Col3"来自" Tab1"
我想避免更改查询引擎。
那么,EF 6中是否有任何选项可以在Oracle中创建带有非加引号标识符的表?
非常感谢......
答案 0 :(得分:2)
这里的诀窍是,您不需要取消引用的标识符,只需将所有标识符强制为全部大写。在Oracle中,未引用的标识符将转换为目录中的所有大写字母。然后,在解析SQL时,Oracle会将SQL中的非引用标识符转换为所有大写字母以匹配目录中的标识符。
这就是Oracle如何创建非案例敏感目录的错觉。
您可以使用Attributes,Fluent API或自定义约定强制您的实体和属性映射到all-caps数据库标识符。
这里有一个关于如何使用自定义约定来规范化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);
}