entity framework 5 - How does Database.SetInitializer actually work? (EF code-first create database and apply migrations using several connection strings) -


i trying write method create database , run migrations on it, given connection string.

i need multiple connections because record audit log in separate database. connection strings out of app.config using code

configurationmanager.connectionstrings["master"].connectionstring; 

the code works first connection string defined in app.config not others, leads me think somehow getting connection string app.config in manner don't know.

my code create database if not exist is

private static context mycreatecontext(string connectionstring)   {    // put connection string factory method can    appdomain.currentdomain.setdata("connectionstring", connectionstring );    var factory = new contextfactory();    // know need line - cant see how follows uses    database.setinitializer(new migratedatabasetolatestversion<context,datalayer.migrations.configuration>());    var context = factory.create();    context.database.createifnotexists();     return context    } 

the code in migrations.configuration

public sealed class configuration :  dbmigrationsconfiguration<datalayer.context> {     public configuration()     {         automaticmigrationsenabled = false;     } } 

the context factory code

  public class contextfactory : idbcontextfactory<context> {     public context create()     {         var s = (string)appdomain.currentdomain.getdata("connectionstring");          return new context(s);     } } 

thus setting connection string before creating context.
can going wrong, given connection strings same except database name, , migration code runs 1 connection string, doesnt run others?

i wonder if problem understanding how how database.setinitializer works. guessing reflection or generics. how make call setinitializer tie tie actual context?

i have tried following code migrations not run

 private static context mycreatecontext(string connectionstring)     {         database.setinitializer(new migratedatabasetolatestversion<context, datalayer.migrations.configuration>());         var context = new context(connectionstring);         context.database.createifnotexists();     } 

this question appears related

update:

i can migrations working if refer connection string using public mycontext() : base("mycontextconnection") - points in config

i able migrations working on using different instances of context, if created contextfactory class , passed connection referencing global. ( see answer related question link )

now wondering why has hard.

i'm not sure problems facing, let me try

the easiest way provide connection - , sure works way...

1) use 'dbcontext' class name - , define connection in app.config (or web.config). that's easiest, should have connection there matches context class name,

2) if put dbcontext via constructor - consistent , use one. i'd suggest 'read' config connections - , again name 'the same' context class (use connection 'name', not actual string),

3) if none present - ef/cf makes 'default' one - based on provider - and context's class name - isn't want,

you shouldn't customize initializers reason - initializers should agnostic , serve other purpose - setup connection in .config - or directly on dbcontext

also check entity framework code first - how tell app use production database once development complete instead of creating local db?

always check 'where data' goes - before doing anything.

for how initializer works - check other post of mine, made thorough example

how create initializer create , migrate mysql database?

notes: (from comments)

connection shouldn't dynamic - config right place be, unless have reason.
constructor should work fine too.
createdbifnotexists doesn't work 'migration' initializer. can use migratedatabasetolatestversion initializer. don't 'mix'

or - put public mycontext() : base("mycontextconnection") - points <connectionstrings> in config

to point connection - use 'name' , put constructor.

or use somehting configurationmanager.connectionstrings["commentscontext"].connectionstring

regarding entertaining 'multiple databases' migrations (local , remote 1 app) - not related - link - migration not working wish... asp.net entityframework

update: (further discussion here - is adding class inherits violation of solid principles if changes behavior of code?)

it getting interesting here. did manage reproduce problems you're facing actually. here short breakdown on think it's happening:

first, worked 'happily':

database.setinitializer(new createandmigratedatabaseinitializer<mycontext, myproject.migrations.configuration>()); (var flip = false; true; flip = !flip) {     using (var db = new mycontext(flip ? "name=mycontext" : "name=othercontext"))     {         // insert records...         db.savechanges();     } } 

(i used custom initializer other post, controls migration/creation 'manually')

that worked fine w/o initializer. once switched on, ran curious problems.

i deleted db-s (two, each connection). expected either not work, or create 1 db, in next pass (like did, w/o migrations, 'create' initializer).

what happened, surprise - created both databases on first pass ??

then, being curious person:), put breakpoints on mycontext ctor, , debugged through migrator/initializer. again empty/no db-s etc.

it created first instance on call within flip. on first access 'model', invoked initializer. migrator took on (having had no db-s). during migrator.update(); constructs mycontext (i'm guessing via generic param in configuration) - , calls 'default' empty ctor. had 'other connection/name' default - , creates other db well.

so, think explains you're experiencing. , why had create 'factory' support context creation. seems way. , setting 'appdomain' wide 'connection string' (which did actually) isn't 'overriden' default ctor call.

solution see - need run through factory - , 'flip' connections in there (no need static connection, long factory singleton.


Comments

Popular posts from this blog

monitor web browser programmatically in Android? -

Shrink a YouTube video to responsive width -

wpf - PdfWriter.GetInstance throws System.NullReferenceException -