MVC3 code first: migrations and generating the database - asp.net-mvc-3

I'm a bit lost how I should get the entity framework to work with automatic migration. I want:
The database to be created automatically when it doesnt exist
The database to be updated automatically when the model changed
For the latter I'm using DbMigrator. It is rather slow so I don't want to run it every request, and also I have multiple databases in the same application so it cant go in Application_Start which is why I put it in Session_Start like this:
if (Session["started"] == null)
{
// this takes care of any database updates that might be necessary.
MigrationConfiguration configuration = new MigrationConfiguration();
DbMigrator migrator = new DbMigrator(configuration);
List<string> pm = migrator.GetPendingMigrations().ToList();
if (pm.Count > 0)
{
migrator.Update();
}
}
else
{
Session["started"] = "started";
}
Not sure if this is the right way to do it but it seems to work, however it doesnt actually generate the database when it doesnt exist. It gives me a "Cannot open database "db" requested by the login"
I had this working before with the following:
Database.SetInitializer<DbContext>(new InitializerIfModelChange());
This drops the database and generates seed data which is fine for when the database doesnt exist but it also is triggers when the database is changed (in which case I would like DbMigrator to handle it) This was in Application_Start before but I'm not sure what to do with it. I'm afraid that it will conflict with the DbMigrator. How would I set this all up in order to achieve the two things described earlier?

I manually run the Update-Database in the package manager whenever the database needs to be changed. Initially I used the Database.SetInitializer like you did to create the database but have it commented out now.
Checkout Entity Framework 4.3 Automatic Migrations Walkthrough for more advanced help.
This should work for what you want, then if you need to create a new database just add Database.SetInitializer<NewDBContext>(new NewDBInitializer()); like you had, build and run. Then comment it out so it doesn't run in the future on a model change and instead use the Update-Database command in the package manager.

Related

model changed, update database using codefirst

Im using code-first to create a database. And now im trying to make a linq expression to get data out of the database but then i get this error:
"The model backing the 'FantasySport' context has changed since the database was created. Consider using Code First Migrations to update the database"
So i go to package-manager console and types update-database and it says that there is nothing to update.
"PM> update-database
Specify the '-Verbose' flag to view the SQL statements being applied to the target database.
No pending code-based migrations.
Running Seed method."
----EDIT------
Here is the initializer method:
private class SimpleMembershipInitializer
{
public SimpleMembershipInitializer()
{
Database.SetInitializer<UsersContext>(null);
try
{
using (var context = new UsersContext())
{
if (!context.Database.Exists())
{
// Create the SimpleMembership database without Entity Framework migration schema
((IObjectContextAdapter)context).ObjectContext.CreateDatabase();
}
}
WebSecurity.InitializeDatabaseConnection("DefaultConnection", "UserProfile", "UserId", "UserName", autoCreateTables: true);
}
catch (Exception ex)
{
throw new InvalidOperationException("The ASP.NET Simple Membership database could not be initialized. For more information, please see http://go.microsoft.com/fwlink/?LinkId=256588", ex);
}
}
So what is the problem?
You first have to add a migration to update to. You can do it by typing the following command in the package manager console:
add-migration "a custom name for your migration here..."
This will cause a migration to be created, after which you can run the Update-database command from the package manager console.
[EDIT]
The Database.SetInitializer method specifies the strategy for creating and seeding your database on the fly. Since that is what is causing this error, and since we are manually creating and seeding your database through the update-database command, we want to turn it off. http://www.codeguru.com/csharp/article.php/c19999/Understanding-Database-Initializers-in-Entity-Framework-Code-First.htm
To be able to update the database through migrations you have to use the
add-migration "<migration-name>"
command however I've experienced it getting "stuck" sometimes meaning that you will get this error or it will display the usual message that there is a need for another migration step. To solve this make sure that
there is no hidden migration file which was not deleted just removed from the project
always build the project after an add-migration command before issuing the update-database command
make sure the connection string to the database is the same in the project you issue the update-database command points to the same database your program uses.
Other than this you can check whether the __MigrationHistory table contains all the migration steps including the newest as the Entity Framework tests the current model against this table's records.
Some of these voodoo (like rebuilding and cleaning) was only required around EF 4.4 I guess the update-database script was improved in this area as well.

EF6 with new database generates 'The model backing the <Database> context has changed since the database was created.'

I have been developing a Code First database via migrations for a couple of weeks. I added a few tables yesterday and got the error
The model backing the 'DanceDb' context has changed since the database was created.
After trying a couple of things I dropped the database, removed all code migrations, cleaned the solution, added a single migration and ran an Update-Database but I still get the same error.
If I run Add-Migrations again, nothing is generated so something thinks they're the same.
I'm running VS2013. I have two projects, one for the entities and the other for the MVC project. I've read about moving the entities into the main project but that sounds like a backwards solution if I've ever heard one.
What on earth do I do to get this running again?
A work around is to set the database initializer to null
public class DanceDb : DbContext
{
public DanceDb() : base("name=DanceEntities")
{
Database.SetInitializer<DanceDb>(null);
}
}

Execute Code First Migrations is Grayed Out in Publish Settings

Using Windows Azure and attempting to publish my MVC3 Application. The check box for Execute Code First Migration in the settings panel of the Publish web application is grayed out. What changes do I need to make to be able to enable it?
I believe you see the following "Execute Code First Migration" disabled when you try to publish your MVC application:
This is potentially because either you do not full code written for Code migration in your application as well no or incorrect DB setup in your web.config as described here.
In order to have Code Migration enabled, you must have a DB configured (in case of Windows Azure you need to provide SQL Database info in the web.config) in web.config and a complete class is written on how the code migration will happen depend on your model. Here is an example on how to achieve it.
http://msdn.microsoft.com/en-us/library/dd394698#efcfmigrations
I am assuming that you have Entity Framework model and in your database already (if not then you need to do some reading, answer by #AvkashChauhan would be indeed a good starting point).
However if you do have a model and all the configurations like:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Configurations.Add(new YourEntityMap());
}
and all the entity mappings like:
public class YourEntityMap : EntityTypeConfiguration<YourEntity>
{
public YourEntityMap()
{
this.HasKey(t => t.Id);
}
}
and you still don't get the darn checkbox enabled you might want to do following steps:
Go to Tools > NuGet Package Manager > Package Manager Console
Then in console write
Enable-Migrations -ContextTypeName Company.Models.YourDevContext
where Company.Models.YourDevContext is your Database Context (look for class that inherits from DbContext should be same one that has OnModelCreating override).
after running command you should get something like:
At this point you should have Migrations folder added to the solution more on how to handle migrations here
Hope this saves you some time.

Entity Framework 4.3.1 Migrations - enable automatic migration and creating a new database in the same time

I have played with Entity Framework 4.3 migrations for some time now, but I have trouble achieving the next behavior: In case my code runs on an existing database, I want the database to be migrated automatically to the latest version, but in case the database doesn't exist, the database should be created automatically from the migrations.
I think the problems is related to the first migration that you create. If you create the first migration using -IgnoreChanges parameter (or manually delete them as explained here: http://thedatafarm.com/blog/data-access/using-ef-migrations-with-an-existing-database/), you will not be able to use migrations in order to create a new table using the DbMigrator class. because you don't have the initial migration. If you create the first migration without using -IgnoreChanges, than the migration of the existing database will not be possible. Does anybody has any solution for this problem?
So you have existing database and you want to use migrations on that database and in the same time you want to support database creation by migrations in case of new deployment?
It looks like little bit unsupported use case. The simplest in this case (not tested) would be either conditional compilation or conditional migration driven by some AppSettings key. It means creating initial migration as if you don't have the database and modify Up method to:
public override void Up() {
if (ConfigurationManager.AppSettings["NewDatabaseRequired"] == "true") {
// Here is generated content
}
}
or
public override void Up() {
#if NewDatabaseRequired
// Here is generated content
#endif
}
There is plenty of other more complicated options including scripting your current database, modify the script to end if tables already exist, add a script as a resource to your migration assembly and execute the script in the Up method generated with -IgnoreChanges.
As another option you can open additional database connection and check if tables from migration already exists (by querying sys.tables view in SQL Server). This will not need generated script.

Changes in Model class causes drop database first and recreate, How to avoid this?

In Models context file it was mentioned
If you want Entity Framework to drop and regenerate your database
automatically whenever you change your model schema, add the following
code to the Application_Start method in your Global.asax file. Note:
this will destroy and re-create your database with every model change.
System.Data.Entity.Database.SetInitializer(new System.Data.Entity.DropCreateDatabaseIfModelChanges<HMS.Models.HMSContext>());
so I added this code in the Global.asax file inside protected void Application_Start().
Adding this line drops whole database when I do any changes in model class. Is there any alternate way to avoid this and still I can do Model changes?
i.e After performing changes in model when I rebuild and run my application, it drops my database and regenerate all the empty model tables. So I loose all my entered data and I want to preserve table data.
If you're using EF Code First 4.1, then, no, it will only drop and recreate. EF version 5 apparently supports dynamically changing the underlying database. It's in beta at the moment, but is available for production use if you want to try it out. You can install it through NuGet.

Resources