My schema has evolved over many iterations. I have a set of migrations taking the schema from an empty db to one with dozens of tables and scores of columns.
Along the way there have been several additions of tables, columns and constraints, sometimes followed (in light of experience or new knowledge or changes in the spec) by removal or alterations. Sometimes a table or column name has been re-used or re-purposed.
Now, EF migrations seems perfectly able to run through the sequence creating, altering, dropping, creating again, altering, etc., to get to the latest schema, but it feels wrong. In an extreme case there might be dozens of migrations creating tables followed by dozens more dropping tables until the final schema might be one or two tables (unlikely, I know). An option to go from scratch to just those final tables would feel right.
In my Ruby days with ActiveRecord migrations there was an option to build only the final schema, without stepping through and possibly undoing or redoing work along the way. Of course this meant keeping a complete DDL version of the schema up to date after each migration, but somehow it felt more elegant.
Has anyone done anything similar with Entity Framework?
You might like to try deleting the __MigrationHistory table from your database, removing the Migrations folder (backing up your Configuration.cs file), and then enabling migrations again.
Then start here for PM commands to build scripts
Generate full SQL script from EF 5 Code First Migrations
from code, there is an option on the ObjectContext not directly on DbContext
string script = (context as IObjectContextAdapter).ObjectContext.CreateDatabaseScript();
Of course Automated Migrations would work if you dont need to see the magic and have altered the generated scripts.
Database.SetInitializer(new MigrateDatabaseToLatestVersion<YourDbContext,
YourMigrationConfiguration>()
Context.Database.Initialize(true);
And if it is an EmptyDb Schema, EF will do that for free.
Context.Database.Initialize(true);
Related
Our team is thinking of utilizing Entity Framework Core code-first to help model the database. We can have both DB projects and EF models, as per article here Database Projects vs. Entity Framework Database Migrations utilizing schema compares, just trying to figure out what will be the source of truth?
Does Entity Framework support all features in SQL Server SSDT Database Projects?
What features does EF Core 2 not support? (eg, does it not support any of following: triggers, views, functions, stored procedures, encryption keys, certificates, db properties (ansi null, quoted identifier), partitions)
I am trying to locate the Microsoft Resource.
tl;dr Database Projects are feature-rich, but database-first. Migrations is code-first, but has a very limited built-in set of database features.
For many people it won't be relevant to compare Database Projects and Migrations. They represent two different modes of working with Entity Framework. Migrations is code-first, DP is database-first. Sure, you can use migrations to control the database schema and besides that keep a DP in sync with the generated database to satisfy DBAs (as the link suggests). But both lead their own separate lives and there's no Single Source Of Truth.
So comparing them is useful if you're not sure yet wich working mode you're going to choose.
For me the most important difference is that DP will cover all database objects and detect all changes between them when comparing databases. Migrations only detect changes between a database and the mapped model. And the set of options for generating database objects is very limited. For everything you need additionally you have to inject SQL statements into the migration code. These statements are your own responsibility. You have to figure out yourself if a migration needs an ALTER PROCEDURE statement or not (for example). EF won't complain if the script and the database differ in this respect.
This is the main reason why I've never been a great fan of migrations. It's virtually impossible to maintain a mature database schema including storage, file groups, privileges, collations, and what have you.
Another advantage of DP is that they're great in combination with source control. Each database object has its own file and it's very easy to check the change history of each individual object. That's not possible with generated migrations. Indeed, many intermediate changes may never make it to a generated migration.
Of course the obvious advantage of migrations is the possibility to do a runtime check (albeit incomplete) whether the code and the database match. In database-first projects you need to create your own mechanism for that.
EF Core is only ORM.
1) You should be ready to create all DB objects except tables manually. What I create manually: constrates (defaults as well as conditions). Since this is code first - there is no need in SP, functions and so on. If you use ORM - DB is only storage. Of course practice is important. For me default constraints adds comfort on tables where I create test data manually. And conditions also are usefull in situations when you do not trust your (team) code.
2) you will do creation (and dropping) of views, triggers, sp and so on to the "migration" code (there is such concept in EF) in plain sql:
migrationBuilder.Sql("CREATE VIEW ...");
As a result you could have a separate "migration" program (e.g. command line tool) that install or remove both Ef Core tables and your manually created objects, do and revert the data migrations.
"EF Core migrations" is quite complex api (reserve a week for learning). Interesting topics: managing several dbcontexts in one db, createing db object during migration from model annotations, unistall. Or find a freelancer for it (this part of project is good for outsourcing).
I am in a situation where we have been using (code first) EF migrations against a database that is used as the backing store for two applications. Over the past year or so, we have successfully made DB changes via migrations.
However, at some point a few tables seem to have been manually added and we are now experiencing FK reference errors when we try to delete.
I have attempted the obvious, with the obvious result: Adding the models and generating a migration is going to attempt to recreate the tables in the database.
Is there a strategy to add these new tables to our data model and get our migrations up to date?
I have been updating my entities in development and that resulted in several migrations and update database commands, to a particular database.
What happens if I change the connection string (because the new database sits on a later version of SQL Server, for example) and then run the database update again? I have the impression that EF would detect the new database, run through all of my migrations, and produce one script and execute so that my new database has all the tables, columns, and relationships exactly as how the last migration left it. Can I just change the connection string and I'll get the new database as expected?
Many tell me that I have to create a separate deployment project for each database I want to manipulate with EF, but that seems rather tedious.
If there are different Tables and Columns it will bomb out right away with an Exception on the mismatched column/table name, if your databases are the exact same (and at the same Migration History), it should update it.
If you have two Databases that are not on the same migration history, you can run
Update-Database -TargetMigration migrationName
And this will effectively revert a Migration, just be sure to delete the migration that was added to the solution directory. (This sometimes happens when switching between branches / databases a lot, and may save you some time)
"Can I just change the connection string and I'll get the new database as expected?"
As long as the Migration History isn't mismatched and the Connection String is Pointing to the right place.
"Many tell me that I have to create a separate deployment project for each database I want to manipulate with EF"
If you are using Visual Studio, you can create different publishing profiles if needed
I am working on a system that currently has a number of environments (test, stage, live, etc) each with their own database. So far these databases have been kept in sync by running the same update scripts on each of them.
We are now moving to using EF6 code first migrations, and would also like to start writing some automated system tests using LocalDB.
I've found https://msdn.microsoft.com/pt-pt/data/dn579398 which describes two options for adding an initial migration.
The first method creates an empty initial migration which will work great for the existing environments but won't help with creating LocalDBs for testing.
The second method creates a migration to bring up the whole database from scratch (minus things EF doesn't care about such as sprocs and views). This would be acceptable for testing, but not good for actually recreating a databse. It also requires you to manually comment out the Up method, run the migration on all existing databases, and then put the Up method back. As it will take a while to get the migration through all the environments I'm not keen on this. It also violates the one of the principles of migrations which is that they shouldn't be edited once they've been released.
Having some kind of conditionality in migrations would solve my problem (e.g. if(tableExists("A_table_in_the_existing_database") return;) but there doesn't seem to be anything like that available.
The best I've come up with is to dump the existing database schema from SQL server to a file (which has the advantage of preserving sprocs, views, etc) and then use option 2 above, except instead of using the generated Up method I'll run the SQL file.
However, this still has the drawbacks of option 2 mentioned above, so I'd be very happy to learn of a better way of handling this situation.
Edit:
Would this work? Run the commented out initial migration on one database, then dumping out the __MigrationHistory table and inserting it into the other databases? That way I wouldn't have to wait for the migration to make it through all the environments before I could safely uncomment it.
EF 6.1.2 has support for running SQL embedded as a resource within the assembly containing the migrations using the SqlResource method.
I think I'd go with scripting out your existing schema and using an initial migration that executes SqlResource as its Up. If all it's doing is a bunch of IF EXISTS then it shouldn't take too long to run. Otherwise scripting out __MigrationHistory will also work if you just want to run it once locally and apply to all your other databases by hand.
I've started looking into Entity Framework migrations on 4.3.1. Have a few questions:
What's preferred during development? Why should I not just drop and recreate my
database always and then reseed. If I use code first migrations, can
I choose to seed my db initially and then add a seed method to each
migration to only add in new data? If i use automatic migrations, is
it possible to do something similar? i.e. seed initially and then
seed as required?
What is the benefit of using migrations during development? I only
actually need migrations when moving to production. So, I need to
create my initial script and then scripts for each migration, so
would it be possible to only use migrations once i want to move to
production and at that point create an initial script and maintain a
migration history from that point onwards?
Well, in our case, we started to use Migrations because in our company, devs don't have the necessary rights to create a DB, which lead to the amusing scenario where I dropped the DB a couple of times and had to ask the db admin to recreate it each time...
In my opinion, it seems easier to incrementally grow your DB, rather than having to recreate it each time. If I were to have to drop and recreate our DB every time a property is added, deleted or changed, I'd never see the end of it.
I've not yet seen a possibility for incremental seeds, unless perhaps if you create manual migration files.
Migrations has the possibility to go to a specific version (either forwards or backwards) and it is possible to generate an SQL script from a migration.
So basically, you don't have to create a migration SQL script by hand anymore, you can get Migrations to do it for you.