如何使用 Oracle 和 SQL Server 在 .NET 4.5 C# Entity Framework 6 中将列映射为大写?
How do I map a column to uppercase in .NET 4.5 C# Entity Framework 6 using both Oracle and SQL Server?
我在我的项目中使用 C#、.NET 4.5 和 Entity Framework 6。它同时使用 Oracle 和 SQL 服务器,具体取决于客户端的安装。
该方法是数据库优先的,因为在我们决定将 ORM 从 NHibernate 更改为 Entity Framework 6.
时该数据库已经存在
映射如下所示:
ToTable(schema + ".Motorista");
Property(x => x.Criacao).HasColumnName("criacao").IsOptional();
table 和列名在映射中都是 PascalCase,这在 SQL Server 上工作正常,但在 Oracle 中,所有名称都是大写,这会导致错误:
ORA-00942: table or view does not exist
如果我手动将其设为大写,那么它在 Oracle 上工作正常。但由于与 SQL 服务器的兼容性,我不能这样做。
如何在使用 Oracle 时 Entity Framework 将所有名称大写?
我可以在这种情况下使用约定吗?
检查命名连接字符串中的 providerName 属性以查看您的连接是针对 SQL Server 还是 Oracle(或者在配置的 appSettings 部分添加冗余值)。然后按照@AaronLS 的建议进行操作,并添加一个辅助方法来正确区分您的姓名并应用任何其他格式。 helper 方法的任务是如上所述检查数据库类型并应用或不应用 casing/formatting.
这是一个例子。
public class MyDbContext : DbContext
{
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Configurations.Add(new SomeMappedTypeMapper());
base.OnModelCreating(modelBuilder);
}
}
public class SomeMappedType
{
public int SomeMappedColumnId { get; set; }
public string SomeMappedColumn { get; set; }
}
public class SomeMappedTypeMapper : EntityTypeConfiguration<SomeMappedType>
{
public SomeMappedTypeMapper()
{
this.HasKey(x => x.SomeMappedColumnId);
this.ToTable("SomeMappedType"); // If needed, apply the same technique as used in the column name extension
this.Property(x => x.SomeMappedColumnId).HasColumnNameV2("SomeMappedColumnId").HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
this.Property(x => x.SomeMappedColumn).HasColumnNameV2("SomeMappedColumn");
}
}
public static class TypeHelper
{
private static bool isOracle;
static TypeHelper()
{
isOracle = System.Configuration.ConfigurationManager.ConnectionStrings["yourDbConnectionName"].ProviderName.IndexOf("oracle", StringComparison.OrdinalIgnoreCase) >= 0;
}
public static PrimitivePropertyConfiguration HasColumnNameV2(this PrimitivePropertyConfiguration property, string columnName)
{
if (isOracle)
return property.HasColumnName(columnName.ToUpper());
return property.HasColumnName(columnName);
}
}
当数据库名称(tables和列)等于class和属性模型中的class名称时,很容易引入自定义代码优先约定:
在上下文的 OnModelCreating
重载中,您可以添加这些行以添加约定 table 和列名称分别从 class 和 属性 名称派生的方式:
modelBuilder.Types().Configure
(c => c.ToTable(c.ClrType.Name.ToUpper(), schema));
modelBuilder.Properties().Configure
(c => c.HasColumnName(c.ClrPropertyInfo.Name.ToUpper()));
当然,您应该有条件地执行此操作,即在连接到 Oracle 时。例如,通过检查 OnOracle
之类的全局常量,您可以通过
进行设置
ConfigurationManager.ConnectionStrings[0].ProviderName
== "System.Data.OracleClient"
应用程序启动时。
考虑一个名为 "Person" 的 table 在 SQL 服务器中有一个名为 "Name" 的列,但在 oracle 中 table 被称为 "PERSON"有一个名为 "NAME".
的列
通过将以下代码添加到 DBContext 类的 OnModelCreating
,我们能够在 oracle 数据库上使用针对 sql 服务器生成的模型
modelBuilder.Entity<Person>()
.HasEntitySetName("Person")
.ToTable("PERSON");
modelBuilder.Entity<Person>()
.Property(t => t.Name)
.HasColumnName("NAME");
这个 link 在 EF CORE 中,但它可能对你有帮助,它转换为 ToUpper,但你可以更改为 ToLower,你也可以使用 Nuget ** Humanizer ** 进行另一种大写。
将该文件导入您的项目并像这样使用它。
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.ToUpperCaseTables();
modelBuilder.ToUpperCaseColumns();
// ...
}
我在我的项目中使用 C#、.NET 4.5 和 Entity Framework 6。它同时使用 Oracle 和 SQL 服务器,具体取决于客户端的安装。
该方法是数据库优先的,因为在我们决定将 ORM 从 NHibernate 更改为 Entity Framework 6.
时该数据库已经存在映射如下所示:
ToTable(schema + ".Motorista");
Property(x => x.Criacao).HasColumnName("criacao").IsOptional();
table 和列名在映射中都是 PascalCase,这在 SQL Server 上工作正常,但在 Oracle 中,所有名称都是大写,这会导致错误:
ORA-00942: table or view does not exist
如果我手动将其设为大写,那么它在 Oracle 上工作正常。但由于与 SQL 服务器的兼容性,我不能这样做。
如何在使用 Oracle 时 Entity Framework 将所有名称大写?
我可以在这种情况下使用约定吗?
检查命名连接字符串中的 providerName 属性以查看您的连接是针对 SQL Server 还是 Oracle(或者在配置的 appSettings 部分添加冗余值)。然后按照@AaronLS 的建议进行操作,并添加一个辅助方法来正确区分您的姓名并应用任何其他格式。 helper 方法的任务是如上所述检查数据库类型并应用或不应用 casing/formatting.
这是一个例子。
public class MyDbContext : DbContext
{
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Configurations.Add(new SomeMappedTypeMapper());
base.OnModelCreating(modelBuilder);
}
}
public class SomeMappedType
{
public int SomeMappedColumnId { get; set; }
public string SomeMappedColumn { get; set; }
}
public class SomeMappedTypeMapper : EntityTypeConfiguration<SomeMappedType>
{
public SomeMappedTypeMapper()
{
this.HasKey(x => x.SomeMappedColumnId);
this.ToTable("SomeMappedType"); // If needed, apply the same technique as used in the column name extension
this.Property(x => x.SomeMappedColumnId).HasColumnNameV2("SomeMappedColumnId").HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
this.Property(x => x.SomeMappedColumn).HasColumnNameV2("SomeMappedColumn");
}
}
public static class TypeHelper
{
private static bool isOracle;
static TypeHelper()
{
isOracle = System.Configuration.ConfigurationManager.ConnectionStrings["yourDbConnectionName"].ProviderName.IndexOf("oracle", StringComparison.OrdinalIgnoreCase) >= 0;
}
public static PrimitivePropertyConfiguration HasColumnNameV2(this PrimitivePropertyConfiguration property, string columnName)
{
if (isOracle)
return property.HasColumnName(columnName.ToUpper());
return property.HasColumnName(columnName);
}
}
当数据库名称(tables和列)等于class和属性模型中的class名称时,很容易引入自定义代码优先约定:
在上下文的 OnModelCreating
重载中,您可以添加这些行以添加约定 table 和列名称分别从 class 和 属性 名称派生的方式:
modelBuilder.Types().Configure
(c => c.ToTable(c.ClrType.Name.ToUpper(), schema));
modelBuilder.Properties().Configure
(c => c.HasColumnName(c.ClrPropertyInfo.Name.ToUpper()));
当然,您应该有条件地执行此操作,即在连接到 Oracle 时。例如,通过检查 OnOracle
之类的全局常量,您可以通过
ConfigurationManager.ConnectionStrings[0].ProviderName
== "System.Data.OracleClient"
应用程序启动时。
考虑一个名为 "Person" 的 table 在 SQL 服务器中有一个名为 "Name" 的列,但在 oracle 中 table 被称为 "PERSON"有一个名为 "NAME".
的列通过将以下代码添加到 DBContext 类的 OnModelCreating
,我们能够在 oracle 数据库上使用针对 sql 服务器生成的模型modelBuilder.Entity<Person>()
.HasEntitySetName("Person")
.ToTable("PERSON");
modelBuilder.Entity<Person>()
.Property(t => t.Name)
.HasColumnName("NAME");
这个 link 在 EF CORE 中,但它可能对你有帮助,它转换为 ToUpper,但你可以更改为 ToLower,你也可以使用 Nuget ** Humanizer ** 进行另一种大写。
将该文件导入您的项目并像这样使用它。
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.ToUpperCaseTables();
modelBuilder.ToUpperCaseColumns();
// ...
}