Entity Framework 4 code-based migrations don´t work after calling CreateDatabaseIfNotExist - entity-framework-4

I have a MVC 3 project were I use code based migrations together mith automatic migrations(this works).
When I install this project on a new server the database is created by CreateDatabaseIfNotExist initializer, cause I´m using the seed method of this. After executing this I have a __MigrationHistory table with one entry. The model hash of this entry is exactly the same like the last one from my developement server. On my development server I have an entry for each of my code based migration in the __MigrationHistory table.
Now the problem is that when I try to run the migrations on the new server, I expected them to say to me "nothing to do, cause model hash is same", but instead of this the migrations seems to look only for the MigrationId in the database and try to execute every migration whose MigrationId is missing. Of course this leads to Exceptions, cause the migration tries to add database structures already there.
I think this should be a very common scenario, so is there a kind of workaround for this? My workaround for the moment is to copy all contents from the __MigrationHistory of the development system to the new server, but this is very tricky, due to the dealing with the modelhash as varbinary. Is there a better solution or did I understand some logical things wrong?

Related

Migrations doesn't affect database

I am new to Rails and I am facing the following problem. There were different tables in the existing project schema such as questionnaire, test, answers, questions, etc. But they did not have the columns of the creation date and the update date, and there were no models and views yet. So I decided to delete them and recreate them. Unfortunately I did it directly through the pgAdmin. Then I recreated each model with a scaffold generator. Everything was going fine until I got to the Questions model. For this model, I forgot to delete the table from the database, which I decided to do. But when I returned to the terminal and tried again to migrate the creation of the question table, I came across the same error message that the table already exists. Moreover, in the schema, I found that all tables manually removed from the database are still present.
What I tried:
I wrote migrations to drop tables. Migrations go through, tables disappear from the schema. Then I tried to write again table creation migrations, they are also started and tables are added to the schema, but they are not created in the database itself. But the application is still accessing the database, retrieving data, inserting it (into other tables that I have not touched on).
How can I return everything to the original? Migrations do not work in the project and I do not understand how to fix it. And I would not really like to dump the database, since it contains a lot of data.
Also in the project there are old migrations of test creation, test results, etc., which I deleted manually through the PG Admin. Should I delete them?
db/migrate
I found a bug. The problem was that the project turns out to be using docker (did not fully understand what it is). But as I understand it, for any update of the project, it must be reloaded through 4 commands in the terminal. Therefore, migrations did not go through the terminal. they had to be done by the docker himself. I expected to see the error logs right in the terminal, and they were issued by docker. I should have connected to the docker logs and read errors from there. There, he swore in plain text about the impossibility of migrating due to the lack of tables. I rolled back migrations to the state before the problem, removed migrations conflicting with the current state of the database and created new ones, according to the rails conventions. In the end, everything worked.

EF6 Updating Code First Model from the Database

I inherited an ASP.NET MVC application using Entity Framework 6.2. The application was originally built using Code First and I can see migrations that have been applied to the database. The structure of the database seems accurate.
However, a ton of relationships have been added to fix referential integrity issues and these were done directly on the database. There are a bunch of them. Can someone help me to update the models from the database in a code first implementation? Ideally it would remain code first, not a conversion, but I need to do a one time update.
I'm more familiar with newer EF Core and I thought it would as easy as running a scaffold-dbcontext command with a -force and some cleanup. But no such luck in this older version. Is there something similar?
Depending on what a 'ton' means and whether you need to keep the old migrations you could either just rebuild the entire model by doing code first from existing database or you could save the generated code into a folder and do a manual reconstruction:
Run code first from existing database into a new folder.
Map new fields and navigation properties into existing models.
Fix up any fluent code (modelBuilder).
Generate a migration which should include those changes.
A good test would be restoring a pre-change version of the database and running the migration against it. Then perhaps use a schema compare utility.
Apply the migration to databases. If the database already includes the changes, comment out the Up() code before applying. This will update the stored model so the next migration does not repeat these changes.

Entity Framework bug? "Context changed" Error, even when not

I have gotten myself into an odd Groundhog Day scenario with an MVC application of mine.
Unless I apply my workaround (Later in this question) each time I debug the application I'm presented with this error:
The model backing the 'UsersContext' context has changed since the
database was created. Consider using Code First Migrations to update
the database (http://go.microsoft.com/fwlink/?LinkId=238269).
I have not changed the model.
My workaround workflow is:
Add-Migration WHATEVERNAME (Makes a blank migration)
Delete this migration.
Run: Update-Database
Recompile & Run (Now without error)
Notes:
The __MigrationHistory hashes of the latest migration match in both script and in the database.
I have my MVC application & EF project as separate projects.
I have tried creating an -IgnoreChanges migration, to see if applying this would mitigate the issue. It did not.
This is quite frustrating, how would I solve this issue permanently?
Note: Automatic migrations are not suitable for my scenario.
Well, it's almost impossible to understand what's wrong without knowing much more detail. So all I can do is give you some clues of what you could try.
Stopping and restarting the app should not cause the DB to get out of date. Is it only when debugging? Have you tried running the app without debugging? Then recycle the app pool and running the app again.
Do you have any weird post-build step that will overwrite some DLL in your "bin" folder?
Is your app doing something that changes the database schema, thereby invalidating it when you next start up? Run SQL profiler to check what is happening to the DB when your app starts up.
Migrate back to the first version of your schema, and then back again (backup your DB first):
update-database -TargetMigration:0 -verbose
then
update-database -verbose
Temporarily comment out the bulk of your app to try to isolate the cause.
Create a brand new app with EF configured in the same way, copy the connection string and see if it happens for that. If not, then there must be something different. If yes, then show us your EF settings.
Hopefully something here that could give you an idea at least. Good luck!
Enabling migrations sets up the whole migration system. But to enable automatic migrations you have to include -EnableAutomaticMigrations which simply adds the line
AutomaticMigrationsEnabled = true;
into the newly generated Configurations.cs file.
In conjunction with the database initializer, development turnaround is more streamlined because you no longer have to type add-migration and update-database every time you make a change. That will happen automatically now. However, that’s not enough, if you want column removals you have to also perform step 3, where automatic data loss is supported.
When you are ready to release software (internally or externally) where you need strict version control and to upgrade databases on site, you should remove automatic migrations and add a manual migration point.
This can happen when updating to EF6 which made schema changes to the _MigrationHistory table (https://msdn.microsoft.com/en-us/data/jj591621)
The EF6 version has a new column ContextKey so the migration is probably trying to add that column.
I'm guessing if you scaffold it will just be making those changes - or perhaps there's something you changed a long time ago that wasn't 'picked up' yet for some reason.
OR if you just don't want to deal with it right now you can disable migrations temporarily.
System.Data.Entity.Database.SetInitializer<UsersContext>(null);

Code Migrations is skipping initial code migration

Using Entity Framework 5, we're using Code-First Migrations in our application. Every developer has his own database on which they work.
I have accidently emptied mine: There is nothing in there anymore, no tables, not even the migration history table.
So, I've tried to update the database again through the PM console by executing update-database. It immediatley gives me an error that a table does not exist, while it should be created in my inital code migration.
What is interesting is that the PM console also shows what migrations are being applied, which does not contain the inital create code migration, thus not creating any tables at all, and ofcourse failing at later migrations.
I tried executing update-database -targetmigration:initialcreate which gives me the message that that code migration does not exist, while it is a direct copy/paste from the cs file, so the id must be correct (note: this works for other migrations).
I also tried update-database -targetmigration:0 and update-database -targetmigration: $InitialDatabase which both give me 'Target database is already at version 0'.
I've also tried deleting the database altogether and let EF create it for, didnt work either, it keeps skipping the initialcreate migration.
So how do I get Code Migrations to execute my initalCreate code migration?
Working with EF migrations in a team scenario is not ideal to say the least. The best practice my team follows is to never commit migrations. Migrations are personal and apply only to your particular database instance. If everyone commits their own migrations you end up with a mess, quick.
While not directly related to your question, some may wonder how you deal with production migrations. Simply, you don't. Your Release Manager, or whoever will actually push the release live, should generate SQL to apply all the changes at once, and then hand this off to your DBA, or whoever manages the production database.
That said, in the scenario that you describe, where you database has been emptied. The best fix is to delete all migrations in your Migrations folder. Even and especially, the initial migration (they don't matter, anyways, because you shouldn't be holding on to them outside of your personal codebase). Then generate a new migration, which will trigger EF to compare your current database state (empty) with the state of the app and essentially create a new initial migration based on the current state of your app. Then, you can apply this migration.

How does ASP MVC 4 know which db migration you're on?

I have been developing my app in a code-first approach atop an exisiting database.
Only now do I have a need to run a migration. I don't want to destroy this database when my model changes because it is very large and it has nice sample data in it.
How can I run a migration without the framework telling me that there are pending changes to apply? (The code runs anyway as I do my migrations from Rails-tho I would like to do them from here)
I do not want to set up automatic migrations because I am working on a big database with lots of seeded data that I do not want to delete/recreate. I also want to have control over what is made, deleteded and when.
This is also needed for when I take it to production, I'd like to roll out the changes via Migration instead of manually. How can I migrate by adding in/removing the fields I want and not have EF care about what it is I do?
If I know how it knows which one it is on (like Rails) can I trick her into thinking that she can run the migrations I want?
I thought that setting the initializer by:
Database.SetInitializer<MyDbContext>(new CreateDatabaseIfNotExists<MyDbContext>
would take acre of it, but it does not.
To answer the question in the title, because there's a sys table __MigrationHistory which tells EF that there is a difference in your tables vs what the database has.
As far as how to do it (from package manager console):
Enable-Migrations
In the configuration class set AutomaticMigrations = false;
Set your Database.SetInitializer<Context>(null) so it doesn't DropCreate or Update
AddMigration <name> to queue any pending changes to a change model
Update-Database will call the MigrationName.Up method to alter the database with any changes (sans losing data).
There's a Table "__MigrationHistory" that EF uses to store Migration Name / Order. You can backup this table in your dev environment, then delete these records. When you deploy to production, you run the migrations. Another option is use Database compare (dev / prod) and get scripts to change your tables / data.

Resources