0

I am developing an application with WPF and Entity Framework CodeFirst.
One requirement is that the user could create separate database file per new project.
DbContext :

public class TestContext : DbContext, IUnitOfWork
{
    public TestContext()
        : base("TestContext")
    {
    }

    #region Implementation of IUnitOfWork

    public new IDbSet<TEntity> Set<TEntity>() where TEntity : class
    {
        return base.Set<TEntity>();
    }

    #endregion Implementation of IUnitOfWork

    public DbSet<Destination> Destinations { get; set; }

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

Connection string defined in app config :

<connectionStrings>
    <clear />
    <add name="TestContext" providerName="System.Data.SqlClient" connectionString="Server=.\sqlexpress;Database=databaseName;Integrated Security=True;Connect Timeout=300;MultipleActiveResultSets=true;" />
</connectionStrings>


I've used StructureMap to inject DbContext in IUnitOfWork interface to implement context per request pattern. This is StructureMap config :

ObjectFactory.Initialize(x => x.Scan(scanner =>
{                                       
    x.For<IUnitOfWork>().CacheBy(InstanceScope.Hybrid).Use<SpitfireContext>();
}));

When user creates new project I try to change connection string and force application create database for new project.

public static void ChangeDatabase(Guid guid)
{
    var sqlConnectionStringBuilder =
        new SqlConnectionStringBuilder(ConfigHelper.ActiveConnection);
    sqlConnectionStringBuilder["Database"] = guid.ToString();
    ConfigHelper.ActiveConnection = sqlConnectionStringBuilder.ToString();
    Database.DefaultConnectionFactory =
        new System.Data.Entity.Infrastructure.SqlConnectionFactory(ConfigHelper.ActiveConnectionString());

    Database.SetInitializer(
        new MigrateDatabaseToLatestVersion<TestContext, MigrationConfiguration>());
    using (var context = new TestContext())
    {
        context.Database.Initialize(true);
    }
}

Application just creates database for first project and after that it tries migrate previews database.
I don't create DbConext object directly in my codes so I can't pass connection string to its constructor.
What do you suggest for my problem ?
What's wrong with my code ?

Matt
  • 6,787
  • 11
  • 65
  • 112
Shahin
  • 12,543
  • 39
  • 127
  • 205

2 Answers2

1

That's a tricky part - changing connection strings. It kind of works but has issues.

We had a lengthy discussion on that yesterday. Take a look at this (and related) post of mine - which describes some background of troubles for code based on similar approach.

I'd like to help you further if needed - but I'd need some more info...

Why do you say I don't create DbConext object directly in my codes so I can't pass connection string to its constructor ? You have the TestContext - why not pass it through there?

Also I'm not sure about setting the DefaultConnectionFactory, I'll recheck that. It's allowed to be set but it seems recommended on app startup only, not sure. Look up this link in the meantime (it's for EF6 but code is I think similar - and you can look up the source code) - http://msdn.microsoft.com/en-US/data/jj680699

We came to the conclusion that using the DbContext factory was beneficial in such cases.

Community
  • 1
  • 1
NSGaga-mostly-inactive
  • 14,052
  • 3
  • 41
  • 51
0

Would adding a static property on your DbContext class to store the name of the database (Initial Catalog) and then changing the connecting string so that you insert the database name with string.Format work?

Then you could change the database name at any time the next time a context is made it'll be pointing to a new target.

Malcolm O'Hare
  • 4,879
  • 3
  • 33
  • 53