I am thinking of using Entity Framework 6 Code First for database interaction alongside DbUp for database schema update. The thing is I don't want to use EF migration for reasons. So, the workflow that I've reached to is:
Change model (add POCOs, alter properties, etc)
Run Add-Migration temp_file in Visual Studio Package Manager Console
Run Update-Database -Script in Visual Studio Package Manager Console
Grab the generated sql scripts including insertion of new row in table __MigrationHistory
Create a new .sql file and past the generated scripts
Delete temp_file
Run DbUp
It works perfectly locally and on production server, however I don't feel comfortable with adding and then deleting temp_file every time a new migration is generated (I wish there were a way to permanently stop temp_file being added to the solution.).
So question:
Is there a better way to do database migration with DbUp using Entity Framework?
In most of the cases you can skip steps (2) and (6) by utilizing the Automatic Code First Migrations:
Automatic Migrations allows you to use Code First Migrations without having a code file in your project for each change you make.
By default automatic migrations are disabled. You enable them by adding the following like in your db migration configuration class constructor (usually called Configuration and located under Migrations sub folder):
AutomaticMigrationsEnabled = true;
Some things to consider:
Documentation states that automatic migrations have limitations, so be aware.
You can mix automatic and code based migrations (in other words, the proposed and your current approaches).
The benefits of your current approach is that you can preview how EF interprets your model changes and also add/remove/change parts of the migration code.
The automatic migrations have been deprecated (don't exist) in EF Core, so in EF Core projects you have to use something similar to your current approach, except that you have to keep the generated migration code files.
Maybe this answer is too late, but maybe it will be useful as well. I completely understand your approach to use Entity Framework as ORM and a different tool for schema migration. But choosing DbUp requires you to write manually SQL or generate them as you described above. I suggest considering to use FluentMigrator instead of DbUp. It follows the same philosophy, but allows writing migration steps in C# using fluent syntax. In addition, it supports downgrades, i.e. rollback.
Here is an example:
[Migration(1)]
public class CreateUserTable : Migration
{
public override void Up()
{
Create.Table("Users");
}
public override void Down()
{
Delete.Table("Users");
}
}
Related
I'm creating a new code-first Web application but using the code from another application as a starting point. But I'd prefer to delete all the unneeded migrations from the new project.
Currently, my migrations look like this:
I'm pretty sure that I need to keep ApplicationDbContextModelSnapshot.cs and ApplicationDbContext.cs.
So here are my question is: Can I safely delete all the other migration files?
Note: There is no change I will want to revert migrations in the new application, so that is not a concern.
To summarize your question, you'd like to have a clean slate and not have all the migrations you've accrued over time polluting your migrations folder. I've often needed to do this myself when starting a new project and iterating a lot before being satisfied with my final schema.
The good news is that Entity Framework supports this natively out of the box, with just one caveat: if you ever hand-roll your own migrations (by calling Add-Migration and then editing the resultant migration file), perhaps to add a custom index for perf reasons, you'll have to make sure to recover those in this process.
All you have to do is delete your entire migrations folder (including the snapshot) and start over as though you were creating the project from scratch. Typically when you create your first migration, you've already defined a few entities (that's why you want to create the migration, after all); you're just taking that to the next level and want your entire database in that migration.
Once you've deleted your migrations folder, EF no longer thinks your project has migrations at all -- like I said, you're starting from scratch. So all you have to do is call Add-Migration [MigrationName] (i.e. Add-Migration InitialMigration) and it will scaffold the migration with everything needed to create your whole database.
Note: In my comments, I suggested you would need to call Enable-Migrations first, but that is evidently no longer necessary so you can just jump right into calling Add-Migration.
Why not just delete them and add an empty migration to check? If it breaks then you have your answer. Then just restore from version control.
But what Kirk Woll said is correct. Keep your ApplicationDbContext and add an intial migration.
I'm developing a WPF app utilizing a SQL Server Compact 4.0 database. For the course of this project, we made several changes in the model structure with a number of code-based and later with automatic migrations. They all are stored in the _MigrationHistory table and represented by several migration classes.
Now it appeared that I need to considerably change the model. Since the app is still in the development phase, dropping data in the database is not a concern. I would like to get rid of the whole previous migration history and start a new clean model. So my question is what steps are to remove the whole history of migrations and start a new history with automatic migrations in the future.
What parts of the project must be deleted and how to do it safely?
First Make sure your project is backed up and your database is also backed up. In case something goes wrong.
If your project is setup using entity framework code first,
In the project you can delete all the migration files in the 'Migrations' folder except 'MigrationConfiguration.cs' contained within the project that is using entity framework.
Also if you are not concerned with dropping the database, then go-ahead and delete the entire database, then create a new one with the same name that is configured in your database context connection string found in your project's config file.
Rebuild your solution and create a new migration by typing the command in the package manager console 'add-migration' and provide a name. This will create a new migration to create the database for all your code first models. If the generated migration file looks correct, then run 'update-database' in the package manager to apply the migration to your empty database.
Is it possible to merge all migrations files into one ?
I created initial migration.
dotnet ef migrations add InitialMigration
Source
When ever I have some model change I create new migration update.
But now I have too many migration update files.
Is ti possible to merge all migration files to one ?
Off course drop database is not an option, I have to preserve data !
EF 6.X has a option IgnoreChanges. That is the perfect fit for your scenario. But unfortunately it is not a feature available in EF core.
But there is a workaround.
Step 1 : Delete all the migration scripts in the Migrations folder.
Step 2 : In the package manager console : run
PM> Add-Migration InitialCreate
Step 3 : Delete both Up() and Down() methods code. Before you do this, keep those methods saved elsewhere as we will need them again in step 5.
Step 4 : run:
PM> Update-Database
It'll insert a new record into __EFMigrationsHistory table.
Step 5 : After that fill the above migration script's (i.e. .._InitialCreate) Up() and Down() method from the content kept in a safe place from Step 3.
That is it. Now you have only 1 migration file :)
Note : EF core with Package manager console (PM) :Package Manager Console
When you want to merge not all but N last migrations, the protocol is not the same:
Revert N last migrations, one by one, each with the 2 following commands:
dotnet ef database update NameOfTheLastMigration
dotnet ef migrations remove
Apply reverts to database:
dotnet ef database update
Create the "merge" migration:
dotnet ef migrations add NameOfTheMergeMigration
One way to do that is removing all migration files physically and adding new one. If your migrations are in "Migrations" folder, you can simply delete it, otherwise you need to delete your "ModelSnapshot" file too. I think this approach can solve your issue.
As a fellow .NET C# developer I concluded that EF migrations were rather poorly designed to interface with source control as they store large binary schema data per migration (bad for source control systems) and cause unending grief when trying to merge migrations from multiple GIT branches (bad for team workflow). So I eventually ditched EF migrations and replace them with something much simpler that would also work with both GIT merges and our DBAs (who only cared for SQL).
I chose the FOSS app MyBatis / Migrate that works with any JDBC supported SQL engine. I've used it with SQL Server, MySQL and Oracle (not Postgres yet). I've also used it with C# / EF projects (I just stopped using EF's migrations). It's a no-brainer so great for novice coders. No dependencies so ok to use for any SQL database project with any application language. Since it's pure SQL you can leverage features specific to your SQL dialect (e.g. In MySQL, you can add a new column after any existing column using the MySQL specific AFTER clause rather than be forced to add it at the end of the table).
You just create timestamped SQL scripts (using their migrate new command) that contains both forward and rollback SQL code for your schema or data migration. Using filenames prefixed with timestamps (instead of version numbers) means your software teams can easily create and later merge multiple migrations files from different git branches - too easy! They just get combined and applied to the database as part of a single release. If you do need to perform complex data migrations you can either code a stored procedure OR you can code a Java class as part of a migration (although this won't help your DBAs).
For DBAs who don't want to deal with VS or .NET, you can use the migrate script command to generate either a forward or rollback SQL script that gathers the sequence of migrations to be applied to a given software release.
You can configure multiple database instances (e.g. development, test, stage, prod) and just select which one you want to apply your SQL migration to using the --env option (e.g. --env=stage). In each database instance it creates a CHANGELOG table that tracks the migrations that have been applied.
To get started ... Install Java JDK 8 and then install this app.
https://mybatis.org/migrations/
Examples:
$ migrate status # Shows migrations applied and "pending" (be applied) to the selected database
$ migrate up 1 # Applies the next migration
$ migrate down 1 # Undo the last migration
$ migrate redo 1 # Undo and apply last migration (handy when developing migrations)
$ migrate up # Applies all pending migrations
$ migrate --env=test status # Show status of the `test` database.
# Emit forward and reverse SQL for a sequence of migrations.
# Just what your DBAs wanted!
$ migrate script 20090804225207 20090804225333 > up.sql
$ migrate script 20090804225333 20090804225207 > down.sql
MyBatis Schema Migrations on YouTube
If you'd prefer to stick with C# code you might want to have a look at Fluent Migrator. It's particularly good for product projects where you need to support multiple database platforms. I've used it project that supported both SQL Server + MS-Access.
I am working on a entity framework project generating the Entity classes using the New-> ADO.NET Entity Data Model -> Code First From Database. I then select nearly 100 tables to generate (not all tables are suitable to go in the model).
Problem is I am regularly updating the schema, and the only way to refresh the model seems to be to delete and start again, which is fine except I have to re-select the nearly 100 tables again.
Is there any easy way of scripting this generation process?
You should look into using Entity Framework Migrations and start doing your schema changes from the code itself
Set the CompanyName.ProjectName.Infrastructure.EfRepository (the project which has your DbContext) as start up project of the solution
Open the Package manager console
Choose CompanyName.ProjectName.Infrastructure.EfRepository as default project
Run the following commands:
Enable-Migrations -ConnectionStringName "EfDataRepository"
Add-Migration Initial -ConnectionStringName "EfDataRepository"
Update-Database -ConnectionStringName "EfDataRepository" -Script -SourceMigration:0
Then delete the auto-generated Migrations folder within the EF project!
Where EfDataRepository is the connection string name.
I've got this error for the 762nd time but this time I am getting it as soon as I attempt to access my Production site, straight after deleting the 'production' database on Azure and then publishing my site.
The model backing the 'PropertyContext' context has changed since the database was created. Consider using Code First Migrations to update the database
I deleted the database because I couldn't fix this issue any other way but it still doesn't work.
Some important points:
I'm using EF6 and publishing to Azure.
This is 1 of 2 projects/sites that uses the same Repo project. I have no
problems with the other one, just this one.
I have tried publishing the problem project first (after deleting the db) and
second with the same result.
I have tried deleting both WEBSITES and the DB from Azure and starting again
I have tried deleting all migrations and starting with a fresh data model
I have tried the following in my Global.asax (in both projects)
Database.SetInitializer PropertyContext>(null); <-- SO won't let me put the first <
and
Database.SetInitializer(new MigrateDatabaseToLatestVersion<PropertyContext, MyConfiguration>());
new PropertyContext().Database.Initialize(true);
I'm using .net 4.5
Why am I getting this error on a new database and how can I get this site to work?
Just ran into the same error in ASP.Net application. In my case I did not use Code First, but I used standard ASP.Net authentication provider which apparently uses Code First, and authentication was broken because of this issue.
Here is quick and dirty solution is you don't care much about existing user records:
For me the solution was to drop the dbo.__MigrationHistory table, authentication started working fine after that. Be aware! This solution is not for everyone! This will fix the problem, but it is potentially risky.
If you cannot afford to lose data in AspNet* tables:
ASP.Net authentication provider automatically creates tables in your database:
AspNetRoles
AspNetUsers
AspNetUserRoles
AspNetUserClaims
AspNetUserLogings
The tables are empty by default, if you haven't created any new logins for your web site, you can use "quick and dirty" solution above. If you do care about preserving user information or just curios how Code First migrations work, follow these steps:
Open your Web.config file and check the name of the connection string you have for your database. It will be one of the records under <connectionStrings> element.
Open Package Manager Console:
Tools –> Library Package Manager –> Package Manager Console
In Package Manager Console window, use a drop-down to set Default Project. Make sure this is the project that contains ASP.Net authentication provider code.
Execute command:
Update-Database -ConnectionStringName MyConnectionStringName
Replace the MyConnectionStringName with the actual name you looked up in web.config.
As a result of this command you will see a new folder "Migrations" with a bunch of code generated by the Update-Database command. Re-build and re-deploy your app, your new migration code will be executed on startup and would bring the database schema in sync with an updated version of ASP.Net authentication provider code.
When using Code First with Migrations, your database creates a table called __MigrationHistory to track the current schema. When you run your application your Entity Framework will check this table to make sure that the database schema matches your database entities. If they do not match, you will get this error.
To update your database follow these steps:
Open the Package Manager Console (View -> Other Windows -> Package Manager Console) in Visual Studio
In the Package Manager Console Window, there is a drop down with your projects in, make sure it is set to the project that contains your DbContext
Make sure that the project that contains your App.Config / Web.Config file is "Set as Startup Project" (If you have multiple Configs, it must be the one with the Database Connection String defined.
Type Update-Database -ConnectionStringName MyConnString where MyConnString is the name (not the actual connection string) of your connection string in your App.Config / Web.Config
If you get an error like this: "Unable to update database to match the current model because there are pending changes and automatic migration is disabled."
You should enable Automatic Migrations and try again.
To enable Automatic Migrations
In the Migrations folder (in the project with your DbContext), open Configuration.cs.
Make sure the Constructor contains: AutomaticMigrationsEnabled = true;
To stop Entity Framework/DbContext from monitoring changes on your database you could simply delete the __MigrationHistory table in your database. It is then up to you to make sure that the database remains updated manually.
MSDN article here
The solution from this is to use the static method SetInitializer and bind to the context a Null value. If you are working on a Web solution, the best position to write the code is in the Application_Start of your Global.asax.cs file.
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RegisterRoutes(RouteTable.Routes);
//...
Database.SetInitializer<MyContext>(null);
}
I got a similar problem this morning. Suddenly the error appeared and couldn't be resolved:
The model backing the 'ApplicationDbContext' context has changed since
the database was created. Consider using Code First Migrations to update
the database
I have one project for MVC and another project for the model, context and repositories. I've been working on it for weeks but today it said stop.
I have tried to delete database, enable-migration, add-migration and update-database so many times that I've lost count. I've added initializers to MigrateDatabaseToLatestVersion as well as DropCreateDatabaseIfModelChanges. All in vain...
What finally made it work was to move model, context and repositories into the MVC project (not something I was keen on)...then it worked right out of the box without any code changes at all (besides namespaces)! Very strange...
I've read so many blog posts during the day trying to solve this problem. One of them (I don't know which one) mentioned a bug in Visual Studio 2013 where reference to DLL files weren't always updated as they should, suggesting that my MVC project missed out something when I was running add-migration and update-database in my separate project. But it's just a guess.
I'm using EF 6.1 and .Net 4.5.1 in my solution.
Got a similar problem! Answer is here
http://www.asp.net/mvc/overview/older-versions/getting-started-with-aspnet-mvc3/cs/adding-a-new-field
(Rick Anderson)
There are two approaches to resolving the error:
Have the Entity Framework automatically drop and re-create the database based on the new model class schema. This approach is very convenient when doing active development on a test database, because it allows you to quickly evolve the model and database schema together. The downside, though, is that you lose existing data in the database — so you don't want to use this approach on a production database!
Explicitly modify the schema of the existing database so that it matches the model classes. The advantage of this approach is that you keep your data. You can make this change either manually or by creating a database change script.
I have spent some hours trying to solve this problem. One project was working, the other one wasn't.
I had different projects referencing different versions of Entity Framework. In my case, I had a Console app and a Windows Service app, both referencing a third project containing code first classes and DbContext.
After running Update-Package EntityFramework everything worked fine in both projects.