Entity Framework 7 commands clarification - migrations add vs. database update? - asp.net

I'm working on an ASP.NET 5 app that uses Entity Framework 7 with migrations to alter the application's Microsoft Sql Server database.
I'm running into a few issues when I reach the migrations step, and I would like clarification on what the Entity Framework commands migrations add and database update do.
It's my understanding that
> dnx ef migrations add Initial
creates a C# file ending in the name Initial in a folder named Migrations containing code that will create tables based on the application model classes, and
> dnx ef database update
executes the code that will add those changes to the database. However, after the migrations add command, the database has already been created, and the console gives an error when I run the database update command, saying that the tables already exist.
From what I've read on different tutorials, it seems like migrations add shouldn't actually affect the database, and the changes would take place when you run database update, but it doesn't look like that's the case.
Can someone explain what each of these steps are doing and how they fit together? Thanks in advance!

dnx ef migrations add shouldn't create the database. I suspect DbContext.Database.EnsureCreated() is being called somewhere in your application code giving it this effect.

Related

How to add a record to __EFMigrationsHistory without actually running the migration in EF Core

I have an issue where I have an existing database which where I have mapped over only certain entities to use with EF Core (the DB has 100s of tables and I dont want classes for all of them.
I scaffolded the starting stage like this
dotnet ef dbcontext scaffold .. etc etc
Where I specified specific tables with the connection string.
I then created an initial migration to snapshot the starting stage with
dotnet ef migrations add Initial
I now want to add a new table based on a new entity. So I created a second migration using
dotnet ef migrations add NewTable
But when i run this using..
dotnet ef database update NewTable
It attempts to add the tables in the initial migration! because I havent ran that migration, so I have no records in __EFMigrationsHistory. But I dont want to run the first migration as I already have the tables which were scaffolded! Initial was just to create a snapshot which is what I thought you have to do.
So is there some way to make it think Initial has already been run? By putting something in
__EFMigrationsHistory? Then I can run the NewTable migration without getting "object already exisits".
Thanks
It ran my latest NewTable migration fine after I removed the previous one, otherwise it was still trying to add objects from the initial migration resulting in "Object already exists".
I find this strange as the statement
'dotnet ef database update NewTable'
specifies which migration I wanted to run, and shouldn't run initial again. Anyway this fix worked fine.

EntityFramework Core production migrations

How do I update the database for production? I've moved the connection string secrets out of the application. Our CI/CD pipeline handles the token replacement within the connection string "template" that remains in the appsettings, and developers won't have production database access.
I had expected to use automatic migrations, only to discover today that Microsoft eliminated that for EF Core.
Will I have to, every time, temporarily overwrite the connection string that normally specifies my local dev copy of the database? It seems that way, but it also seems very janky process to me, so I wonder if I'm missing something.
There seem to be a confusion of what automatic migration means.
Migrations consist of two parts:
generation from the model
applying to the database.
Migration generation in turn could be two types:
automatic - at runtime, current model is compared to model produced by the last migration, and if there are changes, it generates an automatic migration code.
manual - migrations are generated at design time using the design time tools (Add-Migration command). The auto-generated code can be modified. Modified or not, the migration is stored along with the application code.
Regardless of how migrations are generated, they can be applied at design time using the tools (Update-Database command) and/or at runtime.
What EF6 supports and EF Core have removed is the auto-generation. EF Core migrations cannot be generated at runtime - they must be generated at design time and stored with the application code.
Applying them at runtime is achieved with Migrate method called from some application startup point:
dbContext.Database.Migrate();
For more info, see Migrations and Apply migrations at runtime EF Core documentation topics.

MigrateDatabaseToLatestVersion seed() doesn't create tables in database [duplicate]

In my application I enable Code First Migrations with some migrations, Also I use SQL Server Compact for integration test.
When I run my tests, Entity Framework create an empty database and tries to run migration on that empty database and thrown The specified table does not exist.
Based on this report I think usage of Migration in Entity Framework 6 has changed.
I test all Database Initializer with Context.Database.Create(); but in all case tabale's never created.
I don't know that this is EntityFramework's bug or not, but when I made rename the namespace of Migration Configuration class from default (Projectname/Migrations) to any none default name, migration works well.
Context.Database.Create() will not execute migrations! It only creates empty db. To Update database from code to latest version you need to use DbMigrator.Update method:
var migrator = new DbMigrator(new MyMigrationsConfiguration());
migrator.Update();
Alternatively you might use MigrateDatabaseToLatestVersion
Database.SetInitializer(new MigrateDatabaseToLatestVersion<BlogContext, Configuration>());
It is described in details here: http://msdn.microsoft.com/en-us/data/jj591621.aspx#initializer
In case someone still struggles to fix the issue.
The code that follows works for me: add-migration MyFirstMigration
Meanwhile add-migration "MyFirstMigration" with the migration name ramped in quote doesn't work.
There may be previous migration files which the ide may be referring to mostly likely due to caching.
Drop backup and drop target database if it exists, and drop the migration folder.
Now add the migration and you will be good to go.
It does happens when adding model and running add-migration command.
Here is the simplest cause of this issue:
Add a newly added model property into IdentityDbContex class.
Here are the steps:
create model
add property into IdentityDbContex class
run add-migration
update-database

Best practice for using entity framework for post deployment database changes

I am working on a ASP.NET Web Forms project which is expected to experience lots of database changes even after deployment.
Our preference was to use Entity Framework 5, and the Database First design paradigm. However, since we have to make lots of changes to the database even after deployment, if I use database first approach, then every time I update my database, I will have to delete my entire model and regenerate it. Is there any best practices to make this process less painful?
You should use Code First, so that you can use Migrations.
More specifically I'd use manual Migrations.
With manual Migrations you can create Migrations at any point in time. A migration has the following information:
a snapshot of the current model
a set of "instructions" to upgrade from the previous migration
a set of "instructions" to downgrade to the previous migration
Apart from the necessary Migrations, you should add a new Migration when you deploy your app. For example, you can create a migration called "Version 1.0", when you deploy the version 1.0 of your app.
When you finish each new stable version, you simply add a new migration, for it, like "Version 1.1" or "Version 1.2".
The interesting part of migrations shows up when you have a deployed application version and you need to upgrade (or downgrade) to a new version.
There are commands that let you upgrade (or downgrade) a DB from one particular version
to another particular version. You can do it directly specifying a connection to the DB, or create a SQL script which will apply the changes to the DB. For example, if you deployed the version 1.0 in a customer server, and you need to upgrade the software to version 1.2, you can do this:
Update-Database -SourceMigration "Version 1.0" -TargetMigration "Version 1.2"
-Script
This will create a SQL script which can be run on the DB to upgrade from version 1.0 to 1.2.
If you need help about any of the Migrations commands, simply type:
get-help Update-Database -full
(Update-Database is a command name, you can specify any other like Add-Migration)
It's possible that you need to specify the project where the model is in, the connection string name, the name of the project with the .config file or some other things, depending on the specified parameters, and the structure of the projects in your solution.
To get more info on migrations, read MSDN EF Code First Migration.
NOTE ADDED IN EDITION: there is a new DB initializer that can automatically migrate to the latest version when the application runs. I've worked in a real application, and it works like a charm.
ALTERNATIVE SSDT
If you don't want to follow the advice, you can use SQL Server Data Tools (which can be installed inside VS, or work as an independente application, depending on the version you're using).
The idea of this tool is that you can compare projects (which are DB schema snapshots) to existing DBs, and generate the scripts to change the DB to match the schema in the project. (In fact you can compare any combination ofr project and DB)
If you keep versions of your project in a CVS you can even check the changes from one verison of the project to other version of the project.
NOTE ADDED IN EDITION: a SSDT project is a set of scripts that can build the whole DB, including all the objects in its schema. You can create it from an existing DB or viceversa. Then you can keep comparing any combination of DBs and SSDT projects, as soruce or target, and create an apply the scripts neccesary to change each particular object which has changes. (The scripts are created to change the target so that it looks like the source, but you can swap source and target easyly)
This is an alternative solution, but Migrations are much more powerful because you can customize them, for example to fill a "master table" when creating it, to set the initial value of a new column, and so on. If you use SSTD you'll have to do all of that by hand, and carefully keep track of it. So I highly recommend using Migrations.

How to delete and recreate from scratch an existing EF Code First database

I am using EF Code First with EF 5 in VS 2012. I use PM update-database command and I have a simple seed method to fill some tables with sample data.
I would like to delete and recreate my x.mdb. The update history seems to be out of sync. If I comment out all my DBSets in my context, update-database runs with no error but leaves some tables in the DB. As I have no valuable data in the DB it seems to the simplest to reset the all thing.
How can I accomplish this?
If I'm understanding it right...
If you want to start clean:
1) Manually delete your DB - wherever it is (I'm assuming you have your connection sorted), or empty it, but easier/safer is to delete it all together - as there is system __MigrationHistory table - you need that removed too.
2) Remove all migration files - which are under Migrations - and named like numbers etc. - remove them all,
3) Rebuild your project containing migrations (and the rest) - and make sure your project is set up (configuration) to build automatically (that sometimes may cause problems - but not likely for you),
4) Run Add-Migration Initial again - then Update-Database
If you worked the correct way to create your migrations by using the command Add-Migration "Name_Of_Migration" then you can do the following to get a clean start (reset, with loss of data, of course):
Update-database -TargetMigration:0
Normally your DB is empty now since the down methods were executed.
Update-database
This will recreate your DB to your current migration
For EntityFrameworkCore you can use the following:
Update-Database -Migration 0
This will remove all migrations from the database.
Then you can use:
Remove-Migration
To remove your migration.
Finally you can recreate your migration and apply it to the database.
Add-Migration Initialize
Update-Database
Tested on EFCore v2.1.0
Similarly for the dotnet ef CLI tool:
dotnet ef database update 0 [ --context dbcontextname ]
dotnet ef migrations add Initialize
dotnet ef database update
Single Liner to Drop, Create and Seed from Package Manager Console:
update-database -TargetMigration:0 | update-database -force
Kaboom.
How about ..
static void Main(string[] args)
{
Database.SetInitializer(new DropCreateDatabaseIfModelChanges<ExampleContext>());
// C
// o
// d
// i
// n
// g
}
I picked this up from Programming Entity Framework: Code First, Pg 28 First Edition.
dbctx.Database.EnsureDeleted();
dbctx.Database.EnsureCreated();
I am using .net Core 6 and this code is directly stripped out of the Program.cs
using Microsoft.EntityFrameworkCore;
namespace RandomProjectName
{
public class Program
{
public static async Task<int> Main(string[] args)
{
var connectionString = "Server=YourServerName;Database=YourDatabaseName;Integrated Security=True;";
var optionsBuilder = new DbContextOptionsBuilder<YourDataContext>();
optionsBuilder.UseSqlServer(connectionString);
var db = new YourDataContext(optionsBuilder.Options);
db.Database.EnsureDeleted();
db.Database.Migrate();
}
}
}
You should have at minimum initial migration for this to work.
There re many ways to drop a database or update existing database, simply you can switched to previous migrations.
dotnet ef database update previousMigraionName
But some databases have limitations like not allow to modify after create relationships, means you have not allow privileges to drop columns from ef core database providers but most of time in ef core drop database is allowed.so you can drop DB using drop command
and then you use previous migration again.
dotnet ef database drop
PMC command
PM> drop-database
OR you can do manually deleting database and do a migration.
If you created your database following this tutorial: https://msdn.microsoft.com/en-au/data/jj193542.aspx
... then this might work:
Delete all .mdf and .ldf files in your project directory
Go to View / SQL Server Object Explorer and delete the database from the (localdb)\v11.0 subnode. See also https://stackoverflow.com/a/15832184/2279059
Using EF6 with ASP.Net Core 5 I found these commands handy during first initialization of the database:
Remove-Migration -force; Add-Migration InitialMigration; Update-Database;
It removes the last migration (should be the only one), creates it again, then refreshes the database. You can thus type these three commands in one line into the Package Management Console after editing your DbContext and it'll update InitialMigration and database.
A little annoying is that it'll compile your project three times in a row but a least no further manual steps (like deleting the migration files) are necessary.
When you remove an entity you'll need to issue Remove-Database before updating. So the line becomes:
Remove-Migration -force; Add-Migration InitialMigration; Remove-Database; Update-Database;
Problematic here: You need to confirm removing the database + 4 rebuilds.
Take these steps:
Delete those object which should be deleted from the context // Dbset<Item> Items{get;set;}
and in Nuget Console run these commands
add-migration [contextName]
update-database -verbose
It will drop table(s) that not exist in Context, but already created in database
Let me help in updating the answers here since new users will find it useful.
I believe the aim is to delete the database itself and recreate it using EF Code First approach.
1.Open your project in Visual Studio using the ".sln" extention.
2.Select Server Explorer( it is oftentimes on the left)
3.Select SQL Server Object Explorer.
4.The database you want to delete would be listed under any of the localDB. Right-Click it and select delete.
Since this question is gonna be clicked some day by new EF Core users and I find the top answers somewhat unnecessarily destructive, I will show you a way to start "fresh". Beware, this deletes all of your data.
Delete all tables on your MS SQL server. Also delete the __EFMigrations table.
Type dotnet ef database update
EF Core will now recreate the database from zero up until your latest migration.

Resources