How do I map a column to uppercase in .NET 4.5 C# Entity Framework 6 using both Oracle and SQL Server?

时光毁灭记忆、已成空白 提交于 2019-12-05 20:08:58
Igor

Check the providerName attribute in the named connection string to see if your connection is for SQL Server or Oracle (OR add a redundant value in the appSettings section of the configuration). Then do what @AaronLS suggested and add a helper method to case your names correctly and apply any additional formatting. The helper method should be tasked with checking the database type as mentioned above and applying or not applying casing/formatting.

Here is an example.

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);
    }
}

When the database names (tables and columns) are equal to the class and property names in the class model it's very easy to introduce custom code-first conventions:

In the context's OnModelCreating overload you can add these lines to add conventions how table and column names will be derived from the class and property names, respectively:

modelBuilder.Types().Configure
    (c => c.ToTable(c.ClrType.Name.ToUpper(), schema));

modelBuilder.Properties().Configure
    (c => c.HasColumnName(c.ClrPropertyInfo.Name.ToUpper()));

Of course you should do this conditionally, i.e. when connecting to Oracle. For instance by checking a global constant like OnOracle that you could set by

ConfigurationManager.ConnectionStrings[0].ProviderName
    == "System.Data.OracleClient"

on application start up.

Consider a table called "Person" with a column called "Name" in SQL Server but in oracle the table is called "PERSON" with a column called "NAME".

We were able to use our models generated against sql server on our oracle database by adding the following code to the DBContext classe's OnModelCreating

modelBuilder.Entity<Person>()
  .HasEntitySetName("Person")
  .ToTable("PERSON");

modelBuilder.Entity<Person>()
  .Property(t => t.Name)
  .HasColumnName("NAME");
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!