Where the CREATE DATABASE statement is generated in Entity Framework Code First with Migrations? - entity-framework

I need to configure the database created by Entity Framework Code First MigrateDatabaseToLatestVersion class.
Is it possible to influence the database files parameters like size or maxsize? What interests me in particular, is there a way to add database files?
I assume I need to find the moment where the Entity Framework generates the CREATE DATABASE statement and influence it a bit. As far as I understand, the SqlServerMigrationSqlGenerator class is too late because the database already exists at this point.

Edit: According to comment this doesn't work:
You can just add code based migration using Add-Migration command and modify its Up method to execute Sql("ALTER DATABASE ...") and do what ever you want with your database.
Database is created through DbProviderServices - that is a bridging component between EF and specific database server. ObjectContext exposes operations for creating database and generating database creation script. DbMigrator use database creation operation when you execute Update. It checks that if Database exists and if not it uses ObjectContext.CreateDatabase. So if you want to change the process of creating the database you need to implement your own implementation of the migrator to change the way how Update method generates the database (maybe you just need a decorator which will create a database prior to executing DbMigrator.Update operation).

Related

EF6 hybrid CreateDatabaseIfNotExists and MigrateDatabaseToLatestVersion approach

We want to support all of the following scenarios using a EF6 database initializer to create or update an existing database from our EF6 model:
Create and initialize a new database.
Update an existing (legacy) database that has no __MigrationHistory table yet.
Update an existing (migrated) database that already has a __MigrationHistory table.
When using the CreateDatabaseIfNotExists database initializer, it covers only the first scenario. But then we cannot further evolve our data model.
When using the MigrateDatabaseToLatestVersion database initializer with an InitialDatabase migration that creates the base line database, we can support scenario 1 and 3. But it fails to upgrade existing legacy databases because the generated SQL statements are not idempotent. They fail e. g. with a "Table 'xy' already exists" error.
When using the MigrateDatabaseToLatestVersion database initializer with an empty InitialDatabase migration (=empty Up() method body), then we can only support scenario 2 and 3, but we cannot create new database from scratch.
I am looking for a way that combines the best of both worlds and supports all three required scenarios. Unfortunately this seems impossible with the current EF6 design. The problem I am facing is that the DbMigration steps are discovered using reflection and there seems to be no (clean) way to intercept this. What I would like to do is to write an enhanced "hybrid" database initializer that:
1. Checks if the database exists.
2. If not, then execute all migrations (=default behavior of MigrateDatabaseToLatestVersion).
3. Otherwise check if it is already enabled for migrations (i. e. table __MigrationHistory exists).
4. If yes, then execute only the pending migrations (=default behavior of MigrateDatabaseToLatestVersion).
5. Otherwise execute all DbMigrations except the very first "InitialDatabase" migration. This should also create the __MigrationHistory table and include all(!) migrations (including the very first "InitialDatabase" migration).
I don't find a way to implement step 5.
I would be happy with a "hack" that lets me just catch and ignore exceptions from upgrade operations of the first step (with a well-known MigrationId). I already thought about deriving a class from DbMigrator and override the ApplyMigration method with a
try
{
base.ApplyMigration(...)
}
catch
{
...ignore if migrationMetadata.Id=="my well-known id"..
}
block. But this is impossible because the ApplyMigration is internal.
Any ideas on this?

DropCreateDatabaseIfModelChanges not dropping the database

The DropCreateDatabaseIfModelChanges initialisation strategy no longer works in MVC5 with ASP.NET identity.
I'm getting the following error:
The model backing the 'BaseModelContext' context has changed since the database was created. Consider using Code First Migrations to update the database.
What do I do if for now I don't want to use migrations? Shouldn't the fact that I've TOLD it to drop the database that it should then go and do it?

Entity Framework Migrations with a different Database

I am stuck trying to figure out how to set the database to run a migration on.
I have created a new empty project and set up Entity Framework using code first. I have all my classes built.
I want to add a new database and run the migrations on this. I have Migrations working but I can't figure out what database they are running on.
Is it possible to set the database you want to use for the migrations?
Multiple DBs for the same context gets a little tricky. But It is possible:
The essence of the problem is how EF decides which connection to use.
It will access instantiate the context without NO PARAMS during migration.
So depending on how that behaves influences you outcome and success.
Start here:
EntityFramework code-first custom connection string and migrations

How to create some test data using Entity Framework

I'm using EF 4 and MVC in C#,
When my application loads, I would like load create some entities to be added to my database, so where is the best place to add thsi functionality using EF? Global.asax on Start application?
What is a reasonable name convention for the class... BootStrap?
Thanks
If you have existing database you should not include the initialization into your application. The only way how to make this work in existing database is to execute some initialization in Application_Start. The initialization must check existence of every entity you want to insert and insert data only if the entity is not present. Because your database already exists, the initialization logic will have to run every time you restart the application. To avoid this you would also need some flag in the database to mark that initialization was already done (one of inserted entity can be considered as a "flag" but only if the application cannot remove this entity).
EF normally seeds data only when creating database or after database migration.
Edit: If you are creating test data on your test database you should be happy with database recreation each time your model changes (or with migrations) and custom database initializer to seed your data.

EF CodeFirst - Create index after database create

I'm migrating my project from database-first to code-first.
Entity Framework does some nice work creating my new database (that should mimic the old one).
I'm using a combination of data annotations and the fluent API to describe my tables.
My database has a few indexes and I would like Entity Framework to create them as well. It seems the old way to do this is to define your own Initializer and use custom T-SQL.
But now that we have EF Migrations it should be easier to do so.
I can't seem to figure out how to combine CreateDatabaseIfNotExists<> with an automatic migration to create the indexes. I've tried to use the MigrateDatabaseToLatestVersion<,> but it doesn't seem to perform the migration after the Database has been created.
What is the proper way to create indexes and constraints on database creation now that we have Entity Framework 4.3?
Don't use CreateDatabaseIfNotExists if you want to use migrations. Use MigrateDatabaseToLatestVersion from the beginning - it will create your database as well. Put your index creation code (calls to CreateIndex) into Up method of your migration class.
If you already have existing database and you want to use migrations you must first create initial migration.