tom
tom

Reputation: 1822

Entitiy Framework, use same model for two tables with same layout but different table names

I have two tables that have the same layout -

Report Table
   ID
   ReportCol1
   ReportCol2

In another database I have

 Reporting Table
    ID
    ReportCol1
    ReportCol2

I want to use a single entity model called Report to load the data from both of these tables.

In my context class I have

public DbSet<Report> Report{ get; set; }

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Configurations.Add(new ReportMap());
}

In my call to the first database Report table I get the results as expected.

I change the connection string to point to the second database, but I can't change the name of the table in the table mapping.

I don't want to use stored procs for the reason outlined in my comment.

What can I do, short of the tables names in the database(that is not an option).

Upvotes: 2

Views: 1896

Answers (2)

AaronLS
AaronLS

Reputation: 38367

Have you tried this fluent API modelBuilder.Entity<Report>().ToTable("Reporting"); ? You may need to write this so it conditionally does this based on which database you are connecting to. You may need to have your configuration allow you to say "DatabaseA uses this mapping and connection string", and "DatabaseB uses this other mapping and conenctions string", and rather than changing the connection string, you specify which database by some name/key, and your app looks up that name to determine which mapping code to run.

if(dbMappingconfig == DbMapping.A)//some enum you create
{
    modelBuilder.Entity<Report>().ToTable("Reporting");
}

If your goal is to be able to pass these entities to other methods like DisplayReport(Report r) so that you don't have to duplicate code, you could have both Reporting and Report classes implement a IReport interface.

EF also supports inheritance hierarchies, so you could have them inherit from the same class, BUT I havfe a strong feeling that will not work across databases.

If the OnModelCreating doesn't rerun, it's probably already cached. Put modelBuilder.CacheForContextType = false; in there so it doesn't cache it in future, and to clear the current cache I think you can just do a Clean+Rebuild. This will come at the price of rebuilding the model everytime instead of reusing a cache. What you'd really want is use the cache up until the connection string changes. I don't know of anyway to manually clear the cache, but there might be a way. You can manage the model building yourself:

DbModelBuilder builder = new DbModelBuilder();
// Setup configurations
DbModel model = builder.Build(connection);
DbCompiledModel compiledModel = model.Compile();
DbContext context = new DbContext(connection, compiledModel);

But that will introduce additional complexities since you will need to manage the caching yourself.

While searching on this, I came across this that looks like they are trying to accomplish the same thing, as well as having gone down the same page, see Final section in question: How to map an Entity framework model to a table name dynamically

Upvotes: 2

qujck
qujck

Reputation: 14580

Are you able to create the same named view in each database and map to that instead of a variable table name?

I have 2 copies of tables with different names in my solution and deal with that by having 2 contexts and 2 sets of map files (generated text templates)

Upvotes: 1

Related Questions