Change object map to another "unknown" table at runtime

I need to write a C # application that works with a SQL server database created and maintained by an old application. The application creates new tables every year, and the year property in the table name. The number of created tables may vary depending on the number of "sections" created by the user in the application. Therefore, I have to work with tables like Cwx_DRyz (quite explanatory ...), where "wx" can be a section, and "yz" can be a year. An example of a table group might be:

C01_DR07

C01_DR08

C01_DR09

C02_DR08

C02_DR09

C03_DR06

C04_DR12

And all these tables can be represented, for example, by clients. These are clients from different sections and years, but clients with the same structure.

: Client ? "", .

, , Entity Framework , "Table Per Concrete Type Inheritance", .

PS: EF 4.3.1 VS2010

EDIT: ... , ( ).

+5
1

" ", , . , .

, , (tablename), .

" " :

DbContext:

public DbSet<YourEntity> YourEntities { get; set; }
...

// this is called when the db gets created and does the configuration for you => maybe not needed in your case
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    ConfigurationRegistrar configurationRegistrar = modelBuilder.Configurations;

    new GeneralEntitiesConfiguration(configurationRegistrar);
}

GeneralEntitiesConfiguration - im, , , :

public class GeneralEntitiesConfiguration
{
    public GeneralEntitiesConfiguration(ConfigurationRegistrar configurationRegistrar)
    {
        configurationRegistrar.Add(new YourEntityConfiguration());
        //and additional configurations for each entity, just to splitt it a bit and have it more read and maintenance able
    }
}

YourEntityConfiguration - , :

public class YourEntityConfiguration : EntityTypeConfiguration<YourEntity>
{
    public YourEntityConfiguration ()
    {
        ToTable("WhatEverYouLike"); // here you can do any magic to map this entity to a table, just make sure that your properties are mapped to the correct colums
        Property(entity => entity.Id).HasColumnName("YouColumnName");

        //and here you also have to do the other configurations
    }
}

( ) . , . , "DropCreateDatabaseAlways" "DropCreateDatabaseIfModelChanges" = > , . , , ( ):

//before using the context the first time i'm calling, you can ignore the connection string
DbContextInitializer.Init(conString);

public static class DbContextInitializer
{
    public static void Init (string connectionString)
    {
        Database.SetInitializer(new CreateDbThrowExceptionIfModelDiffersInitializer<SMDbContext>());

        using(var dbContenxt = new MyDbContext(connectionString))
        {
            try
            {
                dbContenxt.Database.Initialize(true);
            }
            catch(DatabaseModelDiffersException diffException)
            {
                // some magic...
            }
            catch(Exception ex)
            {
                // TODO: log
                throw;
            }
        }
    }

    public class CreateDbThrowExceptionIfModelDiffersInitializer<TContext> : IDatabaseInitializer<TContext> where TContext : DbContext
    {
        public void InitializeDatabase(TContext context)
        {
            using (new TransactionScope(TransactionScopeOption.Suppress))
            {
                if (!context.Database.Exists())
                    context.Database.Create();
            }

            if (!context.Database.CompatibleWithModel(true))
            {
                throw new DatabaseModelDiffersException("Database Model differs!");
            }
        }

        protected virtual void Seed(TContext context)
        {
            // create data if you like
        }
    }

    // just an exception i'm using for later useage
    public class DatabaseModelDiffersException : Exception
    {
        public DatabaseModelDiffersException(string msg) : base(msg)
        {}
    }
}

, , ! , ;)

+4

All Articles