1

i know you can define the entity's schema name per class by using ToTable("TableName", "SchemaName") but is there a way to set it up so you can set the schema name for all tables in the configuration as i am getting some weird results when i am using some types of relationship mapping and split entity mapping where it is reverting back to the default dbo.TableName in the internal sql queries

see this earlier post for sql output example

2 Answers 2

3

Im having Oracle database-first with EF 4.1, all mappings done with Data Annotations. Different Schema names in Test and Production environments. My solution is to map the Schema dynamically during OnModelCreating with some help of fluent API, reflection and late binding. Iterate through all Context class properties of generic type and do the dirty work. Works for me so far.

public class Context : DbContext
{
    public Context()
        : base(new OracleConnection(ConfigurationManager.ConnectionStrings["OraAspNetConString"].ConnectionString), true)
    {
    }

    public DbSet<User> Users { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        foreach (var p in typeof(Context).GetProperties().Where(foo=>foo.PropertyType.IsGenericType))
        {
            // this is what we are trying to accomplish here -- 
            //modelBuilder.Entity<User>().ToTable("TBL_USERS", "TestSchema");

            Type tParam = p.PropertyType.GetGenericArguments()[0]; // typeof User
            MethodInfo generic = typeof(DbModelBuilder).GetMethod("Entity").MakeGenericMethod(new[] { tParam });
            object entityTypeConfig = generic.Invoke(modelBuilder, null);

            MethodInfo methodToTable = typeof(EntityTypeConfiguration<>).MakeGenericType(new[] { tParam }).GetMethod("ToTable", new Type[] { typeof(string), typeof(string) });
            methodToTable.Invoke(entityTypeConfig, new[] { GetMappedTableName(tParam), currentOraSchemaName });
        }

        base.OnModelCreating(modelBuilder);
    }

    private string currentOraSchemaName = ConfigurationManager.AppSettings.Get("OraSchemaName");

    private string GetMappedTableName(Type tParam)
    {
        TableAttribute tableAttribute = (TableAttribute)tParam.GetCustomAttributes(typeof(TableAttribute), false).FirstOrDefault();
        return tableAttribute.Name;
    }
}

The user class here, with no hard-coded schema mapping --

[Table("TBL_USERS")]
public class User
{
    [Column("USER_ID")]
    public string UserId { get; set; }

    [Column("USER_NAME")]
    public string Name { get; set; }} 
Sign up to request clarification or add additional context in comments.

1 Comment

DbContext is not available in EF4.x. It became available in EF5 onwards. There's a simpler way to change the database schema name instead of working with reflection. stackoverflow.com/questions/9562883/…
0

Since final EFv4.1 version doesn't have public API for custom conventions you cannot change the schema globally from the API.

4 Comments

I ended up defining a config setting and mapping it in totable not quite the solution I was looking for but it will do till something better comes along
problem is, nothing has came along in one and a half years. guys from Redmond just doing conventions for v6. frankly, I don't believe EF will ever have usable conventions like Fluent NHibernate
@ChrisMcGrath Please, share your solution!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.