I changed an entity property from name to Name and the Add-Migration command didn't add the change to the migration file. Is it possible to set the command to pick up on changes with case sensitivity? Or do I have to drop the columns and add them again?
Rename the column from "testname" to something like "testnames". Add migration
Rename column back to "TestName". Add migration
Alternatively, you can manually edit generated migration code
Related
I am working on a new application in .Net 5 using EF Core. After creating some entity classes and doing the first few migrations I discovered that I wanted to change the data type of column and make it the key in one of the tables. I was able to do that without issue and the app works just fine with that change - but now if I try to change anything else in that table like add a new column and do a migration I get the following error: "To change the IDENTITY property of a column, the column needs to be dropped and recreated." I have tried even dropping the entire table - but nothing seems to work.
Whenever your migrations get messed up, especially early in a project, just delete the migrations folder, drop the Migration History table and start fresh with a new initial migration.
I have a project that just started using EF Migrations.
There is an initial migration and an additional, hand-edited migration that defines indexed views. There is no other migration.
I recently added a single property to one class. When I create a new schema, the property is created. However, I cannot see why it is created, since the property is not mentioned in any migration.
If I search the entire source code folder (with subfolders, .) for any mention of that property name, it does not appear in any EF migration code (it only appears in the class where it is defined, and in a few lines of code where the property is accessed).
When I set a breakpoint at the beginning and end of the Up() method for the two existing migrations, I can see that the table is created without the additional property by the initial migration (verified in SSMS), and that the property does not yet exist at the end of the last Up() migration. Sometime after control leaves the last migration, some code creates a column in the database for this additional property.
To try and track this down, I hand-edited this new property into the initial migration. Now, after the Up() method for the last migration exits, I get an SqlException
Column names in each table must be unique. Column name 'MyNewProperty' in table 'dbo.MyTable' is specified more than once.
in the constructor for my DbContext.
The stack trace only shows the code that is instantiating DbContext.
How can I track down where this additional migration is coming from?
If you are not explicitly adding a code-based migration for this new property (using add-migration), but a column is being created it can be determined that automatic migrations are enabled.
Automatic migrations allow Entity Framework to automatically determine the schema changes required to represent any changes made to the domain model, this is what is adding your new column.
You are also wondering why it still tries to add the new column even after you hand edit a code-based migration to add this new column; for each code-based migration there is a generated code-behind file (.Designer.cs) which contains a string IMigrationMetadata.Target property, this returns a string snapshot of what the domain model will look like after this migration has been applied.
When you edit the migration file by hand, this Target property still returns the old string representation of the domain, which does not contain your new property; as a result of this, automatic migrations then attempts to add a duplicate column.
The solution to this is to add your new property to the domain then use the add-migration command to add a new code-based migration for this new property.
We are using EF6 code first approach and we have automatic migrations enabled (we are at the beginning of the project).
Database.SetInitializer(new MigrateDatabaseToLatestVersion<OurDbContext, Configuration>());
And in the Configuration class we have the following enabled in order for the DB to be updated automatically during each application start:
public Configuration()
{
AutomaticMigrationsEnabled = true;
AutomaticMigrationDataLossAllowed = true;
}
The DB column names are explicitly mapped like this (with "HasColumnName") because we want to have full control over the column names:
modelBuilder.Entity<User>().Property(u => u.Gender).IsRequired().HasColumnName("Gender");
I've just noticed today that when I changed the name of the mapped column to begin with a lowercase ex:
modelBuilder.Entity<User>().Property(u => u.Gender).IsRequired().HasColumnName("gender");
... the automatic migration does not detect this as a change to the DB and does nothing i.e. the DB column name stays the same ("Gender" with an uppercase g).
It was only after I changed the column name to another word ex:
modelBuilder.Entity<User>().Property(u => u.Gender).IsRequired().HasColumnName("genders");
...that caused the automatic migrations to actually change the column name in the DB, which indicates that somehow the check for column name is done in a case insensitive way.
Does anyone know if this is by design, or is this a bug in EF?
Additionally is there a way to force the automatic migrations to perform case sensitive column name checks?
Thanks in advance
Case sensitivity does not make much difference to DB, so I believe this is intentional.
If you don't like lowercase column name, just work around this:
Rename the column from "gender" to something like "genders". Add migration
Rename column back to "Gender". Add migration
Alternatively, you can manually edit generated migration code
I'm using Entity framework 5 code first in an Asp.Net MVC app. The app already created a table UserProfile. I moved the class in a different DbContext and also create some new classes for the DbContext; then I ran enabled-migration, add-migration and update-database. I got the following error when update-database.
There is already an object named 'UserProfile' in the database.
How to let EF-code-first don't generate the creating script for the table? However, I will need EF-code first to track the added columns in the class and update the table later.
Use Update-Database -Script for update a database manually. And you can exclude 'UserProfile' from resulting script.
Now i'm using EF6 Alpha, and when using migration, it will add a new migration log into the __MigrationHistory table.
In EF6, The __MigrationHistory table has a new column called "ContextKey". After testing, I found there are two default "ContextKey" value:
The full name of DbContext's derived class.This happens when i run the code:
Database.CreateIfNotExists();
The full name of DbMigrationsConfiguration's derived class. This happens when i run the code:
public ArticleDbContext()
{
Database.SetInitializer(new MigrateDatabaseToLatestVersion<ArticleDbContext, ArticleConfiguration>());
}
The first time i run the application, "Database.CreateIfNotExists();" create a new database for me, also all tables that map to the models defined in ArticleDbContext, and then add a __MigrationHistory row which ContextKey's value is "Module.Article.Model.ArticleDbContext".
And then "Database.SetInitializer(new MigrateDatabaseToLatestVersion());" will be runned, this code will generate a new ContextKey "PowerEasy.Module.Article.Migrations.ArticleConfiguration". Migration query the __MigrationHistory table with this ContextKey and find out there's no data. So again it will create all tables that map to the models defined in ArticleDbContext, but the tables are already exist in the database, so an exception will be throwed, and tell me "the table XXX is already existed".
How can i solve this?
You should not mix Migrations and the Database.CreateIfNotExists method (or any of the initializers built on top of it). Migrations will take care of creating the database if it does not already exist.
As an alternative to the Migrations initializer, you can also apply migrations using the DbMigrator.Update method. This is useful if you want to create/update the database before it would otherwise be triggered by the initializer.