Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>This is my attempt at <code>Db Initializer</code> which combines both <code>Migration</code> initializer and the default <code>Db Create</code> one with seeding. (note: it's not ideal, more like a simple exercise but gives a solution to what you're asking here, mostly works - just check all the updates I made). </p> <blockquote> <p><a href="https://stackoverflow.com/questions/15796115/how-to-create-initializer-to-create-and-migrate-mysql-database/15796416#15796416">How to create initializer to create and migrate mysql database?</a></p> </blockquote> <p>As for the <code>why</code> and <code>how</code> - to fully understand that I'd suggest you also consult the <a href="http://entityframework.codeplex.com/" rel="nofollow noreferrer">EF source code</a> (that's new version but in many ways similar) </p> <h3>1)</h3> <p><strong>a) Db initializer gets called usually only once</strong> (per connection) - and when you try to access your 'model' for the first time (first query or similar). Put a breakpoint in your initializer to check. </p> <p>So it's completely safe to put it within constructor (though I prefer it on startup somewhere, config also). <strong>It only gets called when it's needed to initialize</strong> (and the <code>last one set</code> is used), you shouldn't invoke it manually. </p> <p>Anyhow, to force the initializer you can do the <code>this.Database.Initialize(force: true);</code> </p> <blockquote> <p>For when switching connections see my post on problems<br> <a href="https://stackoverflow.com/questions/15926897/code-first-custom-connection-string-and-migrations-without-using-idbcontextfacto/15938194#15938194">Code first custom connection string and migrations without using IDbContextFactory</a></p> </blockquote> <p><strong>b)</strong> If you create your own <code>IDatabaseInitializer</code> and you still want migrations to work <code>side by side</code> </p> <p><strong>You shouldn't just call <code>DbMigrator</code> from outside</strong> - as your custom initializer will miss on the whole 'db creation' (e.g. if you wish to seed or something - check my example above). </p> <p><strong>Both things are effectively 'initializers' - so you'd need to integrate them into one</strong>, that'd <code>chain</code> things in some way. Have in mind that <code>order of execution</code> is important (see above ex. for problems) - you should check for 'empty condition', then call <code>DbMigrator</code>, then do your own intialization. I used one initializer as a base class, and merged the other. </p> <p>And if you just want to <code>seed</code> - you can use the migration Configuration, that's the simplest if plausible. </p> <h3>2)</h3> <p>Is pretty 'open ended' and there is no single answer. Usually it works, but issues are expexted... </p> <ul> <li><p>Migrations are 3 things (as I see it) - your code model/entities, your database/tables, and the <code>__MigrationHistory</code> system table in the Db. All 3 need to stay <code>in sync</code>. If you get 'out of sync', you can drop the migration table, recreate migrations (with a flag to keep existing db) and then move on as before - i.e. there are solutions for when with live data. For this see <a href="https://stackoverflow.com/questions/9016709/how-to-ignore-a-table-class-in-ef-4-3-migrations/9623319#9623319">How to ignore a table/class in EF 4.3 migrations</a>, </p></li> <li><p>you'd need permissions to drop/create Db for when moving database, </p></li> <li><p>make sure your connection is right (change in config - and in sync with your DbContext name or ctor), </p></li> <li><p>keep it simple, don't do fancy things or switch connections from code (possible but has problems) etc., </p></li> <li><p>don't <code>mix database / code</code> versions - i.e. one code entities version - one database. If you want to share the same Db with different code versions (e.g. staging, production) - don't (multi-tenant solutions will be available in EF6 - e.g. <a href="https://stackoverflow.com/questions/15955145/entity-framework-with-multiple-models-throws-error-stating-the-model-backing-th/15956419#15956419">this</a>), </p></li> <li><p>if you need to manually apply the database - generate the <code>script</code> via <code>Update-Database</code> - and apply that, don't do things manually or you'll get it wrong (the migration history table) - see <a href="https://stackoverflow.com/questions/10254613/mvc3-and-code-first-migrations/10255051#10255051">this one</a>,</p></li> </ul> <p>...that's just to name the few. It is pretty stable and usable IMO - but if you follow the rules - and know what the limitations are.</p> <hr/> <pre><code>class CreateAndMigrateDatabaseInitializer&lt;TContext, TConfiguration&gt; : CreateDatabaseIfNotExists&lt;TContext&gt;, IDatabaseInitializer&lt;TContext&gt; where TContext : DbContext where TConfiguration : DbMigrationsConfiguration&lt;TContext&gt;, new() { private readonly DbMigrationsConfiguration _configuration; public CreateAndMigrateDatabaseInitializer() { _configuration = new TConfiguration(); } public CreateAndMigrateDatabaseInitializer(string connection) { Contract.Requires(!string.IsNullOrEmpty(connection), "connection"); _configuration = new TConfiguration { TargetDatabase = new DbConnectionInfo(connection) }; } void IDatabaseInitializer&lt;TContext&gt;.InitializeDatabase(TContext context) { var doseed = !context.Database.Exists(); // &amp;&amp; new DatabaseTableChecker().AnyModelTableExists(context); // check to see if to seed - we 'lack' the 'AnyModelTableExists' // ...could be copied/done otherwise if needed... var migrator = new DbMigrator(_configuration); // if (doseed || !context.Database.CompatibleWithModel(false)) if (migrator.GetPendingMigrations().Any()) migrator.Update(); // move on with the 'CreateDatabaseIfNotExists' for the 'Seed' base.InitializeDatabase(context); if (doseed) { Seed(context); context.SaveChanges(); } } protected override void Seed(TContext context) { } } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload