c# - Entity Framework Code First without app.config -
i hope able me, because seems i'm totally stuck.
for upcoming projects in our company we'd use entity framework 5 code first approach. played around little while , everytime try use ef our existing libraries, fail because seems ef heavily relies on existing app.config.
in our company, have inhouse database library allows connect various data sources , database technologies taking advantages of mef (managed extensibility framework) database providers. have pass database settings, such host (or file), catalog, user credentials , database provider name, library looks appropriate plugin , returns me custom connection string or idbconnection. we'd use library ef because allows flexible database use change database @ runtime.
so. saw typical dbcontext object takes no parameters in constructor. automatically looks appropriate connection string in app.config. don't such things changed default constructor take dbconnection object get's passed dbcontext base class. no deal.
problems occur when code first model changes. ef automatically notices , looks migration classes / configuration. but: typical migration class requires default parameterless constructor context! pity!
so build our own migration class using idbcontextfactory interface. again, seems idbcontextfactory needs parameterless constructor, otherwise i'm not able add migrations or update database.
further, made own data migration configurator pass context, target database. problem here: doesn't find migration classes, no matter try.
i'm stuck because seems way use ef when connection strings saved in app.config. , stupid because need change database connections @ runtime, , app.config read-only default users!
how solve this?
the answer provided here
https://stackoverflow.com/a/15919627/941240
the trick modify default migratedatabasetolatestversion
initializer that:
- the database initialized ...
- ... using connection string current context
the dbmigrator
still create new data context copy connection string yours context according initializer. able shorten code.
and here goes:
public class masterdetailcontext : dbcontext { public dbset<detail> detail { get; set; } public dbset<master> master { get; set; } // 1 used dbmigrator - not going use in code public masterdetailcontext() { database.initialize( true ); } // rather - going use this, want dynamic connection strings public masterdetailcontext( string connectionstring ) : base( connectionstring ) { database.setinitializer( new custominitializer() ); database.initialize( true ); } protected override void onmodelcreating(dbmodelbuilder modelbuilder) { modelbuilder.conventions.remove<pluralizingtablenameconvention>(); } } public class custominitializer : idatabaseinitializer<masterdetailcontext> { #region idatabaseinitializer<masterdetailcontext> members // fix problem migratedatabasetolatestversion // copying connection string context public void initializedatabase( masterdetailcontext context ) { configuration cfg = new configuration(); // migration configuration class cfg.targetdatabase = new dbconnectioninfo( context.database.connection.connectionstring, "system.data.sqlclient" ); dbmigrator dbmigrator = new dbmigrator( cfg ); // call parameterless constructor of datacontext // connection string above set on in dbmigrator.update(); } #endregion }
client code:
static void main( string[] args ) { using ( masterdetailcontext ctx = new masterdetailcontext( @"database=consoleapplication801;server=.\sql2012;integrated security=true" ) ) { } using ( masterdetailcontext ctx = new masterdetailcontext( @"database=consoleapplication802;server=.\sql2012;integrated security=true" ) ) { } }
running cause 2 databases created , migrated according migration configuration.