How to keep your data when model changes? - entity-framework-6

I am learning entity framework. I am reading through some tutorials about initialization and how there are
CreateDatabaseIfNotExists
DropCreateDatabaseIfModelChanges
DropCreateDatabaseAlways
Custom DB Initializer
to choose from.
This makes me wonder, what does one do when they want to change the schema, but they want to keep the data they have?
I was just using sql directly, I could make temp tables, move stuff over, recreate the table with new columnns, move stuff back, etcv
What do you do when your classes and/or their relationships change in EF?

I think your looking for EF migrations:
https://learn.microsoft.com/en-us/ef/ef6/modeling/code-first/migrations/
for every schema change you create a migration, where you can add or remove tables or columns, or you can even run your custom script.
Each migration has an Up method, these will be applied if you run your migration, and a Down method this is used if you want to roll back to the previous migration for some reason.
With Update-Database you can apply all migrations, and with Update-Database –TargetMigration:{nameOfMigration} you can migrate to a specific version.

Related

Why Migration.BuildTargetModel has so much duplicate code?

I'm setting up EF Core 3.1.3 migrations against an existing SQL Server database.
This is what I've done so far:
Scaffold my model from the existing database.
Add the InitialCreate migration.
Remove the contents of the Up() method in InitialCreate.
Update database to create the __EFMigrationsHistory table.
Then I added a property to an entity class and ran dotnet ef add migration.
Now looking at the BuildTargetModel method of the second migration I see that it contains pretty much the same code as MyDbContextModelSnapshot.BuildModel. I.e. it lists all entities and all their properties and relationships.
What does BuildTargetModel on a migration do? Why does it have to duplicate most of the snapshot code? I would only expect to find the diff in a migration.
As confirmed by the developers of EF Core, this behaviour is by design:
https://github.com/dotnet/EntityFramework.Docs/issues/2288

Core data versioning/migration after deleting entities

I have a database which consists of 3 entities, say
'IronMan', 'CaptainAmerica' and 'SpiderMan'.
With new changes, I want to delete all three entities and create another entity called 'Thanos'.
I would not need to use any of the code and data stored earlier with entities 'IronMan', 'CaptainAmerica' and 'SpiderMan'. Do I need to do core data versioning or migration in this case?
As mentioned in Apple's documentation
https://developer.apple.com/documentation/coredata/using_lightweight_migration
You can add, remove, and rename entities in the hierarchy.
So, yes, you need to provide migration (new version model) but can stick to a light-weight migration, hence it will be done automatically based on changes done between the 2 models.

Recreate database view using migration

Is it possible to recreate a database view using a migration? Migration that was used to create a view on database is no more as per the changes done in some table structures. How do I recreate a view as per the new design? Do I have to drop the existing view and create a new through the migration? Or is there a simpler way without losing data?
If you're talking about a view stored in the database, the usual technique in Rails would be not to do that but use scopes in your ActiveModel instead. This next statement is more with MySQL specifically in mind, but probably true generally: as long as you have the indices properly set up, that approach should be as fast as having a view in the database itself and be more programmatically easy to work with. You can specify calc'd fields in a scope through SQL statements if appropriate, though the usual response to that idea is why not have that be an accessor function in your model (as if it were in the database).
Does this help or am I answering a different question than you had?

Is there a way to undo /remove / rollback EF 4.3 foreign key naming convention?

Using EF code first, we have a db seeding framework that uses dependency injected Db initializers and seeders to populate a dev db with sample test data.
Some of these seeding operations need to import a lot of data, so for a couple of tables, we use actual SQL files with INSERT statements. For some of those insert statements, foreign keys must be diabled then re-enabled:
ALTER TABLE [Schema].[TableName] NOCHECK CONSTRAINT [TableName_FkPropertyName]
-- perform a block of inserts
ALTER TABLE [Schema].[TableName] CHECK CONSTRAINT [TableName_FkPropertyName]
I just updated from EF 4.2 to EF 4.3 and noticed that these no longer work. An examination of the db created by EF shows that the FK's are now named differently:
FK_CodeFolder1.Table1Name_CodeFolder2.Table2Name_DbFkColumnName
Is there any way to remove this naming convention and go back to the original? If not, how is this not a known issue or breaking change?
Update after Ladislav's Reply
Ladislav is right, my above explanation of the new naming pattern was not quite right. I have updated it. The part preceding the . was not the full namespace, but it was the name of a folder in the entity model project. So if I had an entity WidgetAbc in folder AggregateSet1, the fk pattern fragment would be AggregateSet1.WidgetAbc, not just WidgetAbc.
Why do you think it is an issue or breaking change? IMHO it is EF internal behavior - you are using code first and in this approach you were not supposed to work directly with database and especially you were not supposed to base your custom database scripts on hardcoded names because you don't have control over their generation.
I don't think you can revert the behavior but you can start using migrations and code your table definitions - AddForeignKey method should allow you naming your FK constraint.
Btw. I see different naming pattern of FK constraints in EFv4.3:
FK_DependentTableName_PrincipalTableName_FKColumnName

EF4 Code First create new table

Is there a way when i add a new entity to my Code First configuration the table gets automatically added so i don't have to worry about updating my DB with new tables?
you can add
Database.SetInitializer(new DropCreateDatabaseIfModelChanges<YourDbContext>());
in you r application start . It will recreate database for you if you have modified your configuration.
And if you do not want to drop and create database (To incremental development) you can use SqlMigrations. http://www.hanselman.com/blog/EntityFrameworkCodeFirstMigrationsAlphaNuGetPackageOfTheWeek10.aspx
From: http://blogs.msdn.com/b/adonet/archive/2010/12/06/ef-feature-ctp5-code-first-walkthrough.aspx
Setting an Initialization Strategy
In the next section we are going to start changing our model which in turn means the database schema needs to change as well. Currently there is no ‘out of the box’ solution to evolve your existing schema in place. Database evolution is something we are currently working on and a sample of the direction we are heading is provided in a recent design blog post.
There is however the opportunity to run some custom logic to initialize the database the first time a context is used in an AppDomain. This is handy if you want to insert seed data for test runs but it’s also useful to re-create the database if the model has changed. In CTP5 we include a couple of strategies you can plug in but you can also write custom ones.
Add a using statement for System.Data.Entity.Database at the top of Program.cs
using System.Data.Entity.Database;
For the walkthrough we just want to drop and re-create the database whenever the model has changed, so at the top of the Main method in my Program class I’ve added the following code
DbDatabase.SetInitializer<ProductContext>(
new DropCreateDatabaseIfModelChanges<ProductContext>());

Resources