stuck in EF migration limbo - entity-framework

i have somehow gotten my EF5 project into a state where I can't proceed.
When I do an 'update-database' i get:
Unable to update database to match the current model because there are pending changes and automatic migration is disabled. Either write the pending model changes to a code-based migration or enable automatic migration. Set DbMigrationsConfiguration.AutomaticMigrationsEnabled to true to enable automatic migration.
You can use the Add-Migration command to write the pending model changes to a code-based migration.
ok, fine, so i try to 'add-migration', and i get:
Unable to generate an explicit migration because the following explicit migrations are pending: [ ]. Apply the pending explicit migrations before attempting to generate a new explicit migration.
20 GOTO 10 ??
what am i supposed to do at this point? (beyond switching to NHibernate?)

What worked for me was:
Reverting all my changes (making a backup first) back to a known good state.
Doing add-migration DummyMigration. That produced some spurious changes that I commented
Called update-database to add the migration + metadata to the [__MigrationHistory] table.
Make the changes I needed (from the backup of the code I took earlier).
Do the normal add-migration/update-database.
Not ideal, and would be cool to see if there's a better solution, but that worked for me.

For me the issue was that we had renamed the namespace of the migration 2014123456_Initial.cs.
But VS had not regenerated the namespace in its associated 2014123456_Initial.Designer.cs.
Once the Designer.cs was changed to use the same namespace, it all started working again.
(also posted this as an answer here because both questions are so similar)

I changed the following value in my Configuration.cs class from false to true.
AutomaticMigrationsEnabled = true;
In App_Data folder I renamed my project's database - the file with .mdf ending (so a new one will be created), and in Package Manager Console I entered the following command:
update-database
after which the pending migrations ran smoothly.
Note this worked for me, but I'm not 100% if this is the best practice. In any case this Entity Framework Code First guide for migrations says:
"If you get an error that indicates a table already exists and can't be created, it is probably because you ran the application after you deleted the database and before you executed update-database. In that case, delete the Movies.mdf file again and retry the update-database command. If you still get an error, delete the migrations folder.."
Also about AutomaticMigrationsEnabled = true; this MSDN article, Data Points : A Code First Migrations Mystery: Solved tells "Migrations can run automatically, meaning that model changes will be discovered and migrations corresponding to changes will be created and executed on the database. All of this happens at run time during database initialization. Automatic migrations are handy for simple apps, but you have very little control over them and I typically don’t recommend enabling them. I was happy when Code First switched the default to false."

Update-Database –TargetMigration <second_last_migration>
Add-Migration <full_name_including_timestamp_of_last_migration>
You need to include the timestamp so that migrations knows you want to edit the existing migration rather than scaffolding a new one. This will update the metadata for the last migration to match the current model.
Update-Database
Source https://learn.microsoft.com/en-gb/ef/ef6/modeling/code-first/migrations/teams#resolving-the-merge-conflict

I did mistake in creation database
using System.ComponentModel.DataAnnotations;
using System.Globalization;
namespace ProductsManager.Models
{
public class Product
{
public int ProductId { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public string Production { get; set; }
public string Size { get; set; }
public decimal<--- Price { get; set; }
public string Barcode { get; set; }
}
}
after add-migration Initial I realized and changed code to public int Price { get; set; }
did same add-migration DummyMigration and its created in migration folder
080372472_dummyMigration
namespace IdetityBeta.Migrations
{
using System;
using System.Data.Entity.Migrations;
public partial class DummyMigration : DbMigration
{
public override void Up()
{
AlterColumn("dbo.Products", "Price", c => c.String());
}
public override void Down()
{
AlterColumn("dbo.Products", "Price", c => c.Decimal(nullable: false, precision: 18, scale: 2));
}
}
}
So then update-database and problem was solved

I got around this by
Run "Update-Database -Script -Force"
note the last explicit migration attempted before the error "Unable to update database..."
Run "Update-Database -Script -TargetMigration [lastmigration]" using the last migration noted from the previous attempt
I could then run in the script and add a new migration. This is on EF6 and Nuget 2.8 - it may not have worked when the question was posted.

This can happen when you are trying to merge with migration which has the same base as your migration because of which there is model difference in one of migration schema even though that table exists
To solve this problem what you can do is create merge migration by command
Add-Migration -IgnoreChanges
followed by migration name
This creates an empty migration with the current model as a snapshot. Thus this will solve your model difference problem and your tables and models will be in sync

Related

How to update EF models created as "Code First from datebase"?

How to update EF models created as "Code First from datebase"?
I don't have a .edmx file (only a .cs one). How can I update it without deleting it and creating a new one ?
With Entity framework code first approach you do not need .edmx file, instead you need to to define a class derived from System.Data.Entity.DbContext class.
Below is a sample class which works as Data repository.
public class MusicStoreEntities : DbContext
{
public DbSet<User> Users{ get; set; }
public DbSet<Product> Products{ get; set; }
}
Now when you update model classes. you need to first enable migrations using Enable-Migrations command in Package Manager Console.
This command has added a Migrations folder to your project.
Now you need to run following command after making any changes in your model classes.
Update-Database –Verbose command in Package Manager Console.
This commaand will run migrations and update database accordingly.
For more details refer https://msdn.microsoft.com/en-us/data/jj591621.aspx

How to edit previously applied migration without adding another migration in EF code first

I have an applied migration using "haward" db schema.
public partial class CreateCourseCategoryTable : DbMigration
{
public override void Up()
{
CreateTable(
"haward.CourseCategories",
c => new
{
Id = c.Int(nullable: false, identity: true),
Name = c.String(),
Code = c.String(),
})
.PrimaryKey(t => t.Id);
}
public override void Down()
{
DropTable("haward.CourseCategories");
}
}
with this mapping
public class CourseCategoryMapping : EntityTypeConfiguration<CourseCategory>
{
public CourseCategoryMapping()
{
ToTable("CourseCategories", "haward");
}
}
now I want to change the schema from "haward" to "tr"
I dont want to add migration with this one so I thought of just editing directly the source code of the Migration and Mapping.
public partial class CreateCourseCategoryTable : DbMigration
{
public override void Up()
{
CreateTable(
"tr.CourseCategories",
c => new
{
Id = c.Int(nullable: false, identity: true),
Name = c.String(),
Code = c.String(),
})
.PrimaryKey(t => t.Id);
}
public override void Down()
{
DropTable("tr.CourseCategories");
}
}
public class CourseCategoryMapping : EntityTypeConfiguration<CourseCategory>
{
public CourseCategoryMapping()
{
ToTable("CourseCategories", "tr");
}
}
then recreate empty database and issued the command update-database
but its telling that I still have pending changes.
so what I did was issued the add-migration command to check which changes are those. and it seems like it still detects my edits(from "haward" to "tr" schema) even without the migrations table.
where do the model changes being saved? and how to edit directly the source code and reapply the migration? I know its not advisable because thats what migration is for. but I dont want to get my history dirty with just those changes specially if I am only at early development stage.
TL;DR: This is very complicated - it's a lot easier just to add a new migration later to correct the problem.
An Entity Framework migration consists of two parts - the code, and a hash of the model. The hash of the model is used to determine whether the model has changed, and hence whether any new migrations are required.
If you change the model, you change the hash. This hash is stored in the MigrationName.designer.cs file. You cannot just edit the model and change the migration.cs code, as the model no longer matches the model hash. You also need to regenerate the hash for the model.
The only way to do this is to roll your database back, and update the hash.
Consider you have 3 migrations applied:
Migration1
Migration2
Migration3
If you want to apply a change from Migration2 onwards...
Roll back to Migration1: Update-Database -TargetMigration Migration1 -Force (NB - This may cause data loss, so work on a development copy of your database)
Make your model code match what you wanted for Migration 2, and update the code for Migration 2 by hand
Regenerate the designer file for Migration2: Add-Migration xxxxxxxxxxx_Migration2 (use the full name of the migration including the date). This will only update the designer.cs file
Apply Migration2: Update-Database -TargetMigration Migration2
Reapply any model changes to your code for Migration3
Regenerate the designer file for Migration3: Add-Migration xxxxxxxxxxx_Migration3
Update the database to latest: Update-Database
I'm not sure if this helps anyone else, but I was able to edit and re-apply a migration by performing the following:
Delete the record of the migration from the _MigrationHistory table. Find the one with a "migrationId" that matches your migration class file name and delete it.
Manually undo all of the previous migration's changes (which would have been everything in the Down() section of your migration class file before you added the new stuff).
Update-Database (or whatever you do to apply your migrations. I have auto-migration turned on so I just run my app).
My migration was pretty simple so I'm not sure if this will work for everyone.
Enjoy!
There's no easy way of doing this but, if you're using a version control system (Git, Subversion, etc.), there's another option. It's a bit more toilsome but was the only one that worked for me.
Considering you have the following migrations:
Migration1
Migration2
Migration3
Assuming you want to change Migration2, you could follow the steps below:
Create a patch with the changes you want to be applied to Migration2
Check out the commit immediately before the migration you want to avoid (in this case, Migration3 - It will look like you have just created Migration2)
Update the DB to Migration1 - Update-Database -TargetMigration Migration1 -Force
Apply the patch you created on step 1
Recreate Migration2 - Add-Migration Migration2 (it will now contain exactly the changes you want)
Copy the migration files created to a different directory
Revert all the uncommitted changes
Check out the HEAD commit again
Delete the files for Migration2 and Migration3
Copy the files from step 6 back to their original directory
Update the database - Update-Database
Recreate Migration3 - Add-Migration Migration3
Update the database again - Update-Database
I assume, this will be the simple one to followed.
Remove the migration from the code base
and Add the same migration after updating the model class.
Then to update-database command.
This will work.

How can I use Entity Framework to use an existing database, and how can I use migrations to switch between DB versions?

Problem:
You have an existing database that you want to use with EntityFrameworks so that you can make database changes via classes. You also want to be able to use the migration features to switch between versions of the database.
Unfortunately this doesn't work out of the box with an existing database, but you can use the Reverse POCO generator to reverse-engineer your db as if you wrote it from scratch.
Hopefully my step-by-step solution will benefit others, I'm sure I'll be referring to it again in 6 months.
Create new project called MyEF (class library project)
Install the EntityFramework Reverse POCO generator either from here, or within Visual Studio menu Tools|Extensions and Updates menu. select Online|Visual Studio Gallery|Templates|Visual C#|Database, install the EntityFramework Reverse POCO generator.
Using Package Manager console, install EntityFramework by Install-Package EntityFramework
Add a new C# item called MyDB.tt using the template: EntityFramework Rever POCO Code First Generator
Add a connectionStrings section to the app.Config class and point to your database.
e.g.
<connectionStrings>
<add name="DefaultConnection" connectionString="Data Source=CP8;Initial Catalog=TestDB;Integrated Security=True;Connect Timeout=15;Encrypt=False;TrustServerCertificate=False;" providerName="System.Data.SqlClient" />
</connectionStrings>
In the file MyDB.tt, change "MyDbContext" to "DefaultConnection" or whatever your connection name is. Save the TT file and the Reverse POCO generator will reverse engineer the database and build your code-first classs for you.
If your database has a _MigrationHistory table, delete it!
In the package manager console (PMC) issue the following
Enable-Migrations –EnableAutomaticMigrations -Force
add-migration Initial
Go to your migrations folder and replace the contents of your XXX_Initial.cs class with
namespace MyEf.Migrations
{
using System;
using System.Data.Entity.Migrations;
public partial class Initial : DbMigration
{
public override void Up()
{
}
public override void Down()
{
}
}
}
From the PMC, issue: update-database
Change your Model by editing the adding a new property in MyDb.cs to the MyTable class:
// MyTable
public class MyTable
{
public int Id { get; set; } // Id (Primary key)
public string Name { get; set; } // Name
public string Sex { get; set; } // Sex
public int? Age { get; set; } // Age
public bool AmIAwesomeOrWhat { get; set; }
}
Rebuild the solution
Issue a command to save your new migration, and update the database
add-migration MyNewProperty
update-database
The following commands will switch to whatever Migration you want.
update-database -targetmigration:Initial
update-database -targetmigration:MyNewProperty

tables are not reflecting on database on vs 2013 by using code first approach of EF 6.1

I have created model classes and using following context in my mvc project on VS2013 and using EF 6.1
public class DataBase : DbContext
{
public class DataBase : DbContext
{
public DataBase()
: base("Db")
{
}
public DbSet<table> table{ get; set; }
}
}
"Db" is my connection string everything ,everything run good but table are not created on my database
Did you try this?
public class DataBase : DbContext
{
public class DataBase : DbContext
{
public DataBase()
: base("Name=Db")
{
}
public DbSet<table> table{ get; set; }
}
}
Set :base() to "Name=Db".
In ef 6 they changed how things work and therefore you need to do some manual steps to be able to generate the database. You have a couple of options I think:
1. Use the packed manager console and run the Update-DataBase command. (You'll have to figure out which flags to use) This might require you to make a blank db with the expected name before running update.
2. Change your database initializer command to:
Database.SetInitializer<UserDbContext>(new MigrateDatabaseToLatestVersion<UserDbContext, Configuration>());
This should make your code always update/create the database. Probably not what you want for production environment though..
3. You create your own initializer, which also has the benefit of seeding data to database on creation. Have a look at http://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc/creating-an-entity-framework-data-model-for-an-asp-net-mvc-application <-- towards the end of the article there is an example of such an initializer. The chapter heading is "Set up EF to initialize the database with test data"

How to recreate migrations from scratch

I recently upgraded from EF6 alpha 1-3 to EF6 beta 1. This meant that I had to recreate all the migrations created using the alpha version.
So I tried to roll back to a migration created using EF5. But I hit the error Introducing FOREIGN KEY constraint on table may cause cycles or multiple cascade paths. I figure this is because I had neglected to fix Down migrations when I was fixing Up migrations for exactly the same problem. (Should have read this before)
Anyway, rather than try to fix it all up I am trying to reset all the migrations - as described here. I deleted my migrations table in the database and all migration .cs files, then in package manager Enable-Migrations -EnableAutomaticMigrations -Force and Add-Migration Initial
When I tried to run my application with my existing database initialiser (which has automatic migrations false) it failed because it tried to create tables that were already there. So I changed my initialiser to Database.SetInitializer(new DropCreateDatabaseAlways<MyContext>())
This time I got the Introducing FOREIGN KEY constraint on table may cause cycles or multiple cascade paths problem again during initialisation
So I changed ALL the cascadeDelete: true to cascadeDelete: false in the migration file
But I still get the same error!
Update 1 I removed all but the creation of 1 table in the migration file but I got the same error. There must be some kind of cache somewhere or it's picking up a file I don't know about or it's generating its own migration in the background
Update 2 I figured that when using DropCreateDatabaseAlways that EF must always generate the migrations and also that changing cascadeDelete to false in the migration file is the wrong place to do it. It should be done in the FluentAPI. So I added this line modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>(); to onmodelcreating. And I also deleted the Initial migration file. Then I ran the application and it correctly generated a database. I thought I'd cracked it but....
I changed initialisation to use my original configuration file:
internal sealed class Configuration : DbMigrationsConfiguration<SID2013Context>
{
public Configuration()
{
AutomaticMigrationsEnabled = false;
AutomaticMigrationDataLossAllowed = true;
}
protected override void Seed(etc..
}
Then I ran the application and it reported that the model had changed. So I did Add-Migration Update-Database and a migration file to create the database was created.
The problem now is that when I run the application it tries to run another update (even though AutomaticMigrationsEnabled = false). I get the "There is already an object named 'xxx' in the database" problem again. There is an entry in the migrations table that does not match the name of the configuration file.
If you would like to start work "code first migration" using an existing database, you can do the following:
I run the add-migration "InitialMigrations".
It explores the existing database and make it a migration step.
temporarily delete the contents of the "InitialMigrations" step:
public partial class InitialMigrations : DbMigration {
public override void Up()
{
//...
//...
}
public override void Down()
{
//...
//...
}
}
I run the update-database
This creates the appropriate entries in the table __MigrationHistory.
Restores the contents of the "InitialMigration" Go to work properly on an empty database.
That's it.
update: initializer
As I understand it, the 'DropCreateDatabaseAlways' always delete and create the database. This can only be used for the very first installation. If you have a working installation launchpad, you erase all data. That is why I hazardous.
I based on this article: coding.abel.nu/2012/03/… my own Initializer I'm using. I'll write.
The seed is definitely executed, so this method yields the same result, but it works even if you do not run installation, but run upgrade.
public partial class MyEntities : DbContext
{
static MyEntities()
{
Database.SetInitializer<MyEntities>(new ValidateDatabase<MyEntities>());
}
}
/// <summary>
/// http://coding.abel.nu/2012/03/prevent-ef-migrations-from-creating-or-changing-the-database/
/// </summary>
/// <typeparam name="TContext"></typeparam>
public class ValidateDatabase<TContext> : IDatabaseInitializer<TContext>
where TContext : DbContext
{
public void InitializeDatabase(TContext context)
{
if (!context.Database.Exists())
{
throw new ConfigurationErrorsException(
"Database does not exist");
}
else
{
if (!context.Database.CompatibleWithModel(true))
{
//from:
//http://stackoverflow.com/questions/11611322/ef-4-3-code-first-migrations-seed-per-migration
var cfg = new Migrations.Configuration();
var migrator = new DbMigrator(cfg);
///Last in the db, (first, the reverse order)
var dbLast = migrator.GetDatabaseMigrations().FirstOrDefault();
///last in the app
var appLast = migrator.GetLocalMigrations().LastOrDefault();
///what is missing
var pendings = string.Join(", ", migrator.GetPendingMigrations());
throw new InvalidOperationException(
string.Format("The database ({0}) is not compatible with the entity model ({1}). Pending migrations: {2}",
dbLast, appLast, pendings));
}
}
}
}
update: setup
Installation I'm using something like this:
http://coding.abel.nu/2012/04/update-database-msi-custom-action/
I finally fixed this by dropping the database manually then running the application with the original MigrateDatabaseToLatestVersion initializer. I had not realised that this would create the database if it did not exist and there was no need to use a DropCreateDatabaseAlways initializer then change to MigrateDatabaseToLatestVersion