I am trying to reset migrations to a clean slate according to this guide:
https://weblog.west-wind.com/posts/2016/Jan/13/Resetting-Entity-Framework-Migrations-to-a-clean-Slate
The problem is that one DB table contains an unique index which was added in one of the migrations
CreateIndex("Localization_Resources", new string[] { "Culture", "Key" }, unique: true, name: "UX_Localization_Resources_Culture_Key");
and this index is not regenerated into the clean initial data migration when I run add-migration Initial according to the guide.
Why is this index not generated into the initial migration? How can it be solved? Thank you.
If it was not part of migration then you have to manually add the unique index using fluent API like below example.
modelBuilder.Entity<YourEntity>()
.HasIndex(b => b.PropertyName)
.IsUnique();
Related
A table had a fine working _context.update(datarecord) in the Edit post controller.
However, it was decided that instead of updating it, every change should become a new entry.
So _context.add(datarecord)
But thats a problem, since EF is _context aware (you where updating Datarecord.keyxxx)
The key fields are auto generated EF does it for you.
And one may not write a key as keys are protected, which is still fine to me.
There hacks around that, just google :
Cannot insert explicit value for identity column in table 'table' when IDENTITY_INSERT is set to OFF
But why go hacking, why alter the DB table enabling, when that future isn't recommended.
Better leave it to SQL/EF core to generate a new key entry for you.
But then how do I alter the _context to select a new entry.
And be able to add or update that new entry instead?
(when i'm at the Edit controller)
solution is simple EF core accepts :
var mymodel is new MyTable
{
// in here set all model fields except index keys
}
_context.yourdb.Add(mymodel);
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 am fed up of using/running Add-Migration and Update-Database because lot of time we forget to run migrations on production database. So, we decided to delete all migrations from database table as well all migration classes. So, what if my __MigrationHistory table remains always empty and no migration classes. What is the main disadvantage?
No this is a bad idea, the [__MigrationHistory] is used to compare your current used conceptual model with the storage model.
1) Case: DbMigrationsConfiguration automatic:
[__MigrationHistory] keeps track for the last migration.
this.AutomaticMigrationsEnabled = true;
this.AutomaticMigrationDataLossAllowed = true;
as shown in the image above, the migrationId is the migration identifier and the model column is a base64 representation of the binary stream of your current conceptual model.
2) Case: DbMigrationsConfiguration non-automatic:
[__MigrationHistory] keeps track of every migration.
this.AutomaticMigrationsEnabled = false;
this.AutomaticMigrationDataLossAllowed = false;
Each migration level obtain a migrationId identifier which is used for migration level up/level/down.
Best practice: If you want to use the automatic migration just regenerate the migration and shipped to the custmer.
If you are using non-automatic migration.
1) If the customer need the data then just tranform the data with SQL to the new db schema
2) If the customer does not need the data then just drop the database an create it again with initialCreate.
If you want to create the database without any migrationHistory info:
// Create the database. You can generate it from SMO "Script database as" and if the database exist then just ignore the creation
// Do not forget to remove the [__MigrationHistory] rows.
DbContext.Database.ExecuteSqlCommand("SQLCreateDbScript.sql");
Database.SetInitializer<MyDbContext>(null);
using (var dbContext = new MyDbContext())
{
// Create DbContext and it works!
dbContext.Users.Add(new User());
dbContext.SaveChanges();
}
I hope this will help you to solve the problem!
And if you want something really with less Db-Schema then use NoSql with EF.
In Core version still not done but with the old version EF6 it is possible todo that (NoSql Db) with: http://www.brightstardb.com or use the Polyglot appoarch from microsoft https://msdn.microsoft.com/en-us/library/dn271399.aspx
Recently i upgraded from EF5 to EF6 and here is list of items which one needs to take care of
EF MiniProfiling: if you were using mini profiling with EF5 you will have broken code as few of the functiionality or variable names had been changed.
Resolution: Upgrade to newer version of EF MiniProfiling
Db-Reindexing: After updating to EF6 it complaints you about change in your model and when you do "Add-Migration" you will see all your index for primary key were getting recreated also its changing name of tables where you have one to one relationship so previously if it generates table name as TableATableB then it will rename table as TableBTableA dont know why.
Resolution 1: Let EF create migrations for create index , just comment out line in
up and down function.
Resolution 2: Copy line of code from down function(i.e. drop index) and try to execute it before it create index , simple rule first drop and then create, you need this else EF will complaint about index already present.
Migrations: This will only affect you if you are doing using some tool to deploy you assemblies and which in turns uses migrate.exe typically found at
...#your project location\packages\EntityFramework.6.1.0\tools\migrate.exe
copy it to your bin folder and things should work fine.
4. Null Handling: In EF6 handling of null values had been changed , my hands on experience says that with ef5 select query was ignoring null cases but is not the case with ef6
e.g. if i have query something like
db.context.entity.where(name != "ab");
and lets say entity table contains two names {"ab",null}
with EF5 it will return 1 row with ef6 it was returning 2 rows
http://entityframework.codeplex.com/workitem/2115
Resolution: If you wanted to work exactly like EF5 you can set
dbContext.Configuration.UseDatabaseNullSemantics = true;
If it helps please don't forgot to mark this post as answered :)
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.