Entity Framework 6 migrations odd behaviour - entity-framework

I am using EF6 Code First with migrations in a new project. I have used this in a few projects already without issue.
Now this new project is against an existing database.
I generated the standard Initial migration file, then deleted all the contents leaving just the Up() and Down() methods. This has worked for me in other projects, but not this time.
When I run update-database from the Package Manager Console, all works as expected.
PM> update-database
Specify the '-Verbose' flag to view the SQL statements being applied to the target database.
No pending explicit migrations.
Running Seed method.
Then I execute the migrations from code (as needed in production) and 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.
I have been trying to get my head around this one for two days, and not getting anywhere.
I have even added another migration file called "stub" and it is generated blank. EF does not see any changes to my model (of which there are none), so it has nothing to generate. Yet the migration execution via code persists with the error that there are migrations pending.
I have attached a logger to the code execution of the migrations and the output is this.
Target database is: 'FMS' (DataSource: (local)\SQL2012, Provider: System.Data.SqlClient, Origin: Configuration).
No pending explicit migrations.
And then I get the error message in my browser.
My configuration class
namespace FMS.Infrastructure.Repository.EF.Migrations.Stage
{
public sealed class StageConfiguration : DbMigrationsConfiguration<StageDb>
{
public StageConfiguration()
{
AutomaticMigrationsEnabled = false;
MigrationsDirectory = #"Migrations\Stage";
CommandTimeout = 3000;
ContextKey = "FMS.Stage";
}
}
}
And the code that performs the migrations
Database.SetInitializer(new MigrateDatabaseToLatestVersion<StageDb, StageConfiguration>());
var dbMigrator = new DbMigrator(new StageConfiguration());
var logger = new MigratorLoggingDecorator(dbMigrator, new DbMigrationLogger());
foreach (string migration in dbMigrator.GetPendingMigrations())
Console.WriteLine(migration);
logger.Update();
I hope this is clear enough for those willing to try assist. If anyone has a tip, I am all ears. This is making me grey.

Related

Update-Database fails on production server

I've enabled migrations for my ASP.NET MVC project. Migrations work perfectly on localhost. However I get the following exception after deploying it to the server:
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.
View Stack Trace
There are no pending migrations, though. Adding a new migration just creates empty Up() & Down()
What could be the reason it doesn't work on the server? I've tried deleting the migrations folder, re-enabling migrations, deleting the database, and let EF do it afresh. The tables get created, but I end up with that exception.
Update:
Another thing I noticed is, when I delete the migration folder but not the database, and enable migrations, it only adds a Configuration.cs file, when it's supposed to add another file too (initialcreate.cs)
This happens when you are doing tow different query on the same list of objects on the same time without using .toList
example :
you can create context and get a list of testObjects then edit one of this objects then save changes
var objectsList = context.testObjects.where(x=>x.whatever=true)
objectsList[0].whatever2="asd"
context.SaveChanges()
the above code will pass the compailer and it will fail while running, to solve this it should be as below
var objectsList = context.testObjects.where(x=>x.whatever=true).ToList()
objectsList[0].whatever2="asd"
context.SaveChanges()

Deploying to Azure not running EF Code First Migrations

I am running Entity Framework with Code First Migrations. My new release adds a table, modifies a few tables, and run some scripts. This works perfectly when developing locally using update-database.
Upon deployment the new table was not created and I was receiving errors from my client. I attached the debugger to the deployed site to track through what was happening. It reached the controller, went through the normal flow, and upon hitting the first database call to the new (but not actually existing yet) table it hopped into the Configuration class for my migration.
internal sealed class Configuration : DbMigrationsConfiguration<myProject.api.AuthContext>
{
public Configuration()
{
AutomaticMigrationsEnabled = false;
MigrationsDirectory = #"Migrations\Auth";
ContextKey = "myProject.api.AuthContext";
}
So I'm thinking great, all should be well. It goes through all of these, returns to the initial database call, but then that call returns an error, pasted below
The model backing the 'AuthContext' context has changed since the
database was created. Consider using Code First Migrations to update
the database (http://go.microsoft.com/fwlink/?LinkId=238269).
This is surprising since indeed I have enabled code first migrations! Using the standard enable-migrations and add-migration, which work perfectly on my local machine when I issue the update-database command.
1) How can I get my Code First migrations to run once deployed to Azure?
Update 1
Here are my publish settings. For some reason I do not have the checkbox option for: "Execute Code First Migrations" and am guessing that's the issue...
Huzzah! My update was the issue. I found from other SO posts that his happens sometimes. A Clean and Rebuild, followed by restarting VS, restored the 'Execute Code First Migrations' checkbox. Re-deployed and everything worked perfectly.
Have you checked these lines of code?
In your web.config:
<appSettings>
<add key="MigrateDatabaseToLatestVersion" value="true"/>
</appSettings>
In your global.asax.cs / Startup.cs (OWIN startup):
var configuration = new Migrations.Configuration();
var migrator = new DbMigrator(configuration);
migrator.Update();

EF6 + SQL Server CE + two contexts+ CodeFirst Migrations from code - Detect Pending Changes after Add-Migration

Entity Framework 6.0.2. .Net 4. I am trying to update SQL Server CE 4.0 database from code, so when a new version of the application is released, the database(s) are automatically upgraded.
There are two data contexts in the project and they are targeting two different databases. This is what I am doing to update one of them:
Private Sub UpdateDatabase(connectionString As String)
Dim config As DbMigrationsConfiguration(Of MainDBContext) = New DbMigrationsConfiguration(Of MainDBContext)()
config.TargetDatabase = New System.Data.Entity.Infrastructure.DbConnectionInfo(connectionString, "System.Data.SqlServerCe.4.0")
config.ContextKey = "MyProject.MainDBContext"
Dim migrator As DbMigrator = New DbMigrator(config)
migrator.Update()
End Sub
The message from the Update method is that there are pending changes so I have to either run Add-Migration or enable Automatic Migrations. However, Add-Migration has been run and when I do allow automatic migrations, Update tries to create tables which already are in the DB.
Running Update-Database works fine when called like this:
Update-Database -configuration MyProject.MigrationsMainDb.Configuration -Verbose
I checked that the connection string used in the UpdateDatabase function is same as the one in the config file (used by Update-Database). I also tried not setting the ContextKey property, but it made no difference.
Is there anything obvious that I am doing wrong? Why does the migrator thinks there are pending updates but Update-Database is fine...?
I made it working. I realized that instead of creating the "generic" configuration class I should create the configuration class which had been added to the project by Enable-Migrations command. So the code has been changed to the following:
Private Sub UpdateDatabase(connectionString As String)
Dim config As MigrationsMainDb.Configuration = New MigrationsMainDb.Configuration()
config.TargetDatabase = New System.Data.Entity.Infrastructure.DbConnectionInfo(connectionString, "System.Data.SqlServerCe.4.0")
Dim migrator As DbMigrator = New DbMigrator(config)
migrator.Update()
End Sub
And this change resulted in the configuration object having properties set up correctly. For example the MigrationsDirectory property, which was not set before to what it should be. This was probably the reason of the issue - the migrator not finding migrations (looking for them in wrong directory) and assuming that the whole model has to be applied to the DB.
After making this change, I still had a small glitch with a pending change. In Visual Studio a file looked like modified, with one extra (test) property in the class, but when I tried to remove the extra line, I got a message from VS like "edited on master", or something like that. I closed the file and reopened - the extra property disappeared. I guess it was something with git, checking out branches and VS not refreshing files properly? Not sure really. But once this line was no longer there and the modified code in place, the Update function started working fine.
Update now updates existing databases and successfully creates new ones. Great :)

Entity Framework Migrations - Seed runs even if no migration?

I have set up a simple Migration with AutomaticMigrationsEnabled = false. Everything works great from visual studio or when using MigrateDatabaseToLatestVersion.
However, this is not ideal for me. I would like to run migrations from a deployment script on my ci server. I found this article explaining how to do this using migrate.exe but this seems to always run the seed. This is even when there are no migrations to apply.
Do I need to check programmatically within the Seed method whether any migrations have been run? How do I do this?
Use DbMigrator to manually run Update() only if there are pending migrations. It was introduced in Entity Framework 5.0.
private void MigrateAndSeedDbIfSchemaIsOutdated()
{
// Disable initializer.
Database.SetInitializer<MyContext>(null);
// Make sure database exists.
using (var db = new MyContext())
{
db.Database.Initialize(false);
}
var migrator = new DbMigrator(new MyConfiguration());
if (migrator.GetPendingMigrations().Any())
{
// Run migrations and seed.
migrator.Update();
}
}

Is it possible to get Entity Framework to recognize previous migrations if you change your project namespace?

Let me break down the scenario:
I create my models/mappings using the code-first approach
I setup a database initializer for MigrateDatabaseToLatestVersion
I create a migration using add-migration
This creates a Configuration class like so:
namespace MyApp.Migrations
{
internal sealed class ConfigurationInfo : DbMigrationsConfiguration<MyContext>
{
}
}
I can run my code and the database will be automatically created with no issue.
Now I go in and change the namespace that my Configuration class lives under:
namespace MyApp.Data.Migrations // <-- new namespace
{
internal sealed class ConfigurationInfo : DbMigrationsConfiguration<MyContext>
{
}
}
I drop the database and rerun the code. I now get this message:
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.
When I renamed the namespace that Configuration lived under it no longer recognizes any of the migrations that were previously created.
I did a lot of experimenting and when I set MigrationsNamespace equal to the old value in the Configuration constructor like so:
namespace MyApp.Data.Migrations
{
internal sealed class ConfigurationInfo : DbMigrationsConfiguration<MyContext>
{
public ConfigurationInfo()
{
AutomaticMigrationsEnabled = false;
MigrationsNamespace = "MyApp.Migrations"; // <-- this works
}
}
}
Now everything works, except all of the previously created migrations need to live under the old namespace in order to work, as well as all future ones (which get the old namespace automatically).
This workaround didn't really do what I wanted to do, which is be able to refactor my code and still have entity framework recognize my previous migrations.
What if the name of my project changes, but I have multiple installations out there that are depending on the MigrateDatabaseToLatestVersion database initializer to receive schema changes to my code?
Am I locked into using the same namespace for my DAL as soon as I enable migrations?
This was my own fault, I did the refactor by hand and thought that I had changed the namespace for all files in my project, but I forgot to expand the migration files and update the "designer" files as well!
When I set the same namespace between the configuration file, the migration files, and the migration designer files everything works great, and I can change the namespace at any time without EF losing track of the old migrations.