EF 6.1.3 automatic migrations - entity-framework

I created an initial migration into my database when I executed a database operation via code first.
All the tables got created successfully.
I have successfully enabled automatic migrations.
I've added a couple of columns to a model.
When I run the "Update-Database –Verbose", I get an error message (which I understand, but don't now why it's coming out) of "There is already an object named 'Categories' in the database."
The Categories table along with all the rest of the tables got created on the initial migration (as explained above).
I made a change (adding the two other columns) to another model (Customer).
I would think, that the Code First migration would simply look at the entire DBSet model, determine what changed, then simply apply the necessary SQL. Instead, it's trying to create the Categories table again which already exists.
Can someone please explain to me how I can simply update the DB without this happening? What am I doing wrong or what do I need to do in order to get it to work....
EDIT
Successful creation of EF code-first Migrations setup:
Enable-Migrations -EnableAutomaticMigrations
Add-Migration Initial (Creates _Initial.cs file).
Comment out code in _Initial.cs file within Migrations folder for
code that you don't want to execute AFTER initial DB run to create tables.
Set Configuration.cs file to Public access
Add following code in Global.asax file
Database.SetInitializer(new
MigrateDatabaseToLatestVersion());
Update-Database - Verbose (for any DB changes)
Set "AutomaticMigrationDataLossAllowed = true;" in Configuration.cs
file within Migrations folder. (for any DB changes)

Related

How to change the column type in table using Entity Framework core

Hi I created my database using Entity Framework core with code first approach. Now there is a change in the column type from int to varchar/string? I can change the column from the database itself but my understanding is that it won't be a good idea and would create issues. I searched through but I didn't get my answer on the net for Entity framework core.
You should use EF Core migrations to update your db schema. The documentation is pretty good, so make sure to go through it.
However, this is a summary of how the process would be:
Make the change in your model (which by convention will be automatically detected. Alternatively, use the Fluent API in your DB Context OnCreate method or in your EntityConfigurations).
Add a migration running the following CLI command : dotnet ef migrations add SomeDescriptiveNameAboutWhatThisMigrationWillDo.
A migration file with an Up and Down method will be automatically generated. The Up will be run when you apply the migration, and the Down if you ever decide to revert it . You could add changes to the automatically scaffolded migration file. Based on the code in the migration file, EF Core will then generate a SQL script and apply the changes to the DB.
Once you have added (and maybe edited) the migration file, you need to apply it to the DB. You do that by running dotnet ef migrations update.
EF Core tracks all applied migrations in a table in your DB called by default __EFMigrationsHistory
In your particular case of changing a column type, EF Core might try to drop the column and recreate it, which will result in data loss. If you wanna keep your data, I would recommend altering the migration script to actually split the process in two: first add a new column with the new type and a slightly different name, then write some custom SQL to migrate data from the old column to the new one, then delete the old column and finally rename the new column to the correct name. To be honest, I am not sure if there is some custom migration operation that will out of the box change the data type without data loss, there might be.
To double check if the migration will generate data loss or check if it will do what you expect it to do, you can generate the SQL script that will be used by running dotnet ef migrations script <from migration> <to migration>. After reviewing it, you can either copy/paste and run the script in your DB, or just run the command detailed in step 4 above.
You can modify your database schema to match your domain model with the add-migration command.
After changing the type of the property on your c# class from int to string, simply run
add-migration <SomeDescriptiveName>
After the creation of the migration files, you can apply them with the update-database command.
You can read more about migrations here.

EF migrations won't recognize existing tables

I've set up this project from DB first and everything went fine. I can debug properly. But when I try make a change to one of my models, instead of the new migration showing a simple AlterColumn statement, it keeps trying to reinitialize the entire database.
I've tried running update database -script and only inserting the _MigrationHistory table record. Even after that, it still wants to create all the tables.
Has this ever happened to anyone?
When you start with an existing database you need to do an empty (no-op) migration to set a baseline. This is because EF will use the model in the prior migration to compare, so if there is not one (in code) you get all your database objects. Inserting a record into __MigrationHistory just tells EF the code migration has been applied - it doesn't use it for the compare.
enable-migrations
add-migration MyBaseline -IgnoreChanges // no Up() code, but model saved
update-database
// Now I can change my model and generate a migration with difference
See here.

Code first migrations not being seen

I'm fairly new to Entity Framework and I am having trouble getting it to apply my code first migrations to a new database. I think my migrations have gotten into a bad state.
I started out with an existing database, so I created an initial empty migration using
Add-Migration Initial -IgnoreChanges
That worked fine. Then I added a new entity and created another migration
Add-Migration New_Entity
That worked fine. I could apply these migrations to an existing database that didn't even have a __MigrationHistory table and it would be properly updated.
Fast forward a few days and a few commits later. I now have a new "clean" database that I want to apply the migrations to. I got into Visual Studio, point my app.config file at the new database, run
Update-Database
And it tells me
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.
However, I do not have any pending models changes. Nothing has changed. But just to see what would happen, I ran
Add-Migration x
and it created a new migration that would add every entity in the model to the database. Basically starting over as if I had no migrations. So I deleted that one then re-added with the -IgnoreChanges flag. That gives me another blank one. If then run
Update-Database
It runs the x migration but totally ignores the migrations I created a few days ago (Initial and New_Entity). It's like it doesn't know they exist.
Obviously something is in a bad state but I'm not sure what I can do to get it back. I can't just delete and recreate the migrations because I need a blank one and one with just the new entity. I can't just comment out the entity temporarily because a lot of code already depends on it.
How did I get myself into this mess and how do I get out?
Alright, I got to the bottom of this. Turns out that somehow (I can't recall how at this point) the namespace inside the Configuration.cs file (inside the Migrations folder) was changed. Apparently this is enough to confuse the system into not seeing your other migrations. I thought at first it was simply because it was out of synch with the actual migration classes that had been generated. However, I tried changing the migration classes' namespaces to match the new namespace value of Congiguration.cs but the migrations still failed. It only worked after I reverted Configuration.cs back to its old namespace value.
Not really sure exactly what the deal is here. Maybe the original namespace was stored in the migration resx files and it noticed they didn't match anymore?

Restoring tables in entity framework

I am working with EF very first time. For some reason I was having difficulty to run my application and every time I was getting exception that your model is not synced up with the current database. I tried everything and since data wasn't important, I thought to re-create all tables by running all the migrations. So, I removed all tables and tried to run the following command. I am using model based approach here to define my entities.
Update-database -targetMigration:InitialCreate -verbose
I was under the impression that it will re-create all tables starting from the very first migration but it actually reverted all to that very first point. Now, whenever i run update-database command, I always get the following
No pending explicit migrations.
I am very confused what should I do to take my table generated back and set my app in working condition. Can anybody help?
Thanks
-Fahad
If you are using model first then you can click on the Model whitespace and do "Generate database from Model". If you are doing code first, EF creates a table on the database called "__MigrationHistory". If you delete that table code first will recreate the database model from your current code based model.

How to skip previous ef migrations on a new database that already contains those changes?

The scenario I'm having problems with is as follows:
Code First model created using EF 4.1 and corresponding database generated
EF upgraded to 4.3.1 and a migration added (using IgnoreChanges because no model changes) to start using migrations (__MigrtionHistory table created and EdmMetadata dropped) - let's call it 'InitialMigration'
Model is changed, say a new property is added and a migration that adds a corresponding column is generated (let's call this one 'NewPropertyMigration') and then applied to a Dev database (using our version of Migrate To Latest initialization strategy)
When code is promoted to production the database there is updated with new column as expected
Then when a brand new database is created in Dev and because it is based on latest model it will include the new column right after it is created but when the initialization strategy is run it still finds 'InitialMigration' and 'NewPropertyMigration' as pending but they both fail because EdmMetadata is not there so nothing to be removed and new column is already there so can't add
When I check __MigrationHistory table on this new database it only contains 'InitialCreate' entry so that would explain why the other two migrations are considered as pending. But I can't see how they would ever get into this table without being applied and at the same time they don't really need to be applied because database already contains any changes they cover.
What am I missing?
I'll just add that it seems a bit suspicious that the Model column in 'InitialCreate' is different to the one in 'NewPropertyMigration' even though they represent the same model. Could that be the cause?
Update:
This is the code I use to create new database and apply any migrations automatically at the same time
public class MigratePaymentsToLatestVersion<TContext> : IDatabaseInitializer<TContext> where TContext : DbContext
{
public void InitializeDatabase(TContext context)
{
// Create a brand new database if it doesn't exist but still apply any pending migrations
context.Database.CreateIfNotExists();
var migrator = new DbMigrator(configuration);
migrator.Update();
}
}
Update 2: Simpler scenario showing the same problem
While investigating this further I've been able to reproduce the behaviour in a much simpler scenario described below:
Create simple model and context
In a test application add one entity - with all default settings database is automatically created and object added
Enable migrations - 'InitialCreate' migration is generated
Update-Database - command returns no pending migrations because 'InitialCreation' is already in __MigrationHistory
Delete database and re-run test application - database is re-created automatically again
At this point I can't add any additional migrations or run update-database because 'InitialCreation' migration is seen as pending but cannot be applied because all entities already exist
I have it sorted now. The crucial bit I was missing seems to be related to the way you move from 4.1 to 4.3. I have been following steps from ef-4-3-migrations-and-existing-database. What seems to work better is the procedure described in the SO question how-to-use-migrations-on-an-existing-db.
If you compare both of them you'll see that one relies on -IgnoreChanges when you do first migration (called 'InitialMigration') while the other one creates a full 'InitialCreate' migration that contains your entire model at that point in time. Two important consequences of the latter approach are:
- when creating a brand new database InitialCreate migration, which contains full definition of the model, is used to create database instead of 'the other code' (not sure exactly but guessing that this is the part that is needed when migrations are not enabled) that generates database based on the model
- new database is created with up-to-date model and with all migrations listed in __MigrationHistory
So with the InitialCreate approach I am able to apply migrations to existing databases (for them the InitialCreate is simply skipped because an entry in history is added manually as part of the procedure) and at the same time I am able to create brand new databases and add new migrations to them without getting an error that model and db are out-of-sync.
I hope that helps people who, like me, followed the first procedure.