So I'm stuck with the following situation, maybe you guys can shed some light on this:
Scenario
Our application exists of many client applications (Winforms), each of which use a specific version of the database model using EF Code First Migrations. The client application has the ability to connect to several different databases, which all support the required schema the client needs.
Next we have one central service application. This application is responsible for maintaining databases (creating/removing), and returning connection strings to clients who need access. The client can send a request to this central service to create a new database. One of the arguments of this call is the schema version it needs (as a string). This is where the problem lies:
Problem
The problem is to find out what the highest version of migration is, without providing any connection string or database to connect to. Normally one would use:
var configuration = new MigrationsConfiguration() { ContextType = typeof(CoreContext) };
var migrator = new DbMigrator(configuration);
var versions = migrator.GetLocalMigrations();
but this automatically results into connecting to a database under the hood (if not provided, just .\SQLExpress). This behavior happens even when you explicitly set the DatabaseInitializer to null and provide a DbMigrationsConfiguration implementation with AutomaticMigrations set to false.
Trying to follow the stacktrace I see the following:
at System.Data.Entity.Utilities.DbProviderServicesExtensions.GetProviderManifestTokenChecked(DbProviderServices providerServices, DbConnection connection)
at System.Data.Entity.Infrastructure.DefaultManifestTokenResolver.<>c__DisplayClass1.<ResolveManifestToken>b__0(Tuple`3 k)
at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)
at System.Data.Entity.Infrastructure.DefaultManifestTokenResolver.ResolveManifestToken(DbConnection connection)
at System.Data.Entity.Utilities.DbConnectionExtensions.GetProviderInfo(DbConnection connection, DbProviderManifest& providerManifest)
at System.Data.Entity.DbModelBuilder.Build(DbConnection providerConnection)
at System.Data.Entity.Internal.LazyInternalContext.CreateModel(LazyInternalContext internalContext)
at System.Data.Entity.Internal.RetryLazy`2.GetValue(TInput input)
at System.Data.Entity.Internal.LazyInternalContext.InitializeContext()
at System.Data.Entity.Internal.LazyInternalContext.get_ModelBeingInitialized()
at System.Data.Entity.Infrastructure.EdmxWriter.WriteEdmx(DbContext context, XmlWriter writer)
at System.Data.Entity.Utilities.DbContextExtensions.<>c__DisplayClass1.<GetModel>b__0(XmlWriter w)
at System.Data.Entity.Utilities.DbContextExtensions.GetModel(Action`1 writeXml)
at System.Data.Entity.Utilities.DbContextExtensions.GetModel(DbContext context)
at System.Data.Entity.Migrations.DbMigrator..ctor(DbMigrationsConfiguration configuration, DbContext usersContext)
at System.Data.Entity.Migrations.DbMigrator..ctor(DbMigrationsConfiguration configuration)
This gets a little too much rocket science-like for me. Maybe somebody can explain to me whether it's possible or not to work with EF Code First Models without providing a connection string or database. Or maybe I'm missing a crucial configuration setting?
Regards, Patrick
ps. I currently found a workaround by using reflection of the assembly/namespace in which the migrations resides, and selecting their Id's. That is actually how GetLocalMigrations() actually works.