I've always used the edmx file approach and just run "update from database". Now i am using Code first from existing database.
When the DBA changes the database schema, how do I update my dbcontext file and POCOs to match? Is that what migrations are for? Do I just delete everything int he models folder and re-create?
"Code-First" has two different meanings in EF. It's both a Modeling workflow and a Mapping style. You can do Code-First Mapping with Database-First Modeling. You simply regenerate your entity types after changing the database, or change them manually to match the database change. This is what's called "Code-First From and Existing Database"
Related
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
I'm wondering if this is even possible. I'm writing an app in MVC using ASP.NET Core and EF Core. For the most part I've been doing code-first migrations (that's all I know how to do, as yet) for my entities.
Someone added a table to the database I'm using, and rather than deleting their table and doing it the code-first way, I'd like to just bring their table over using a DB first migration.
Is that even possible to mix and match DB-first/code-first techniques?
If it is, how do I do it? I can't seem to find anything about bringing over just one table. Only migrating a whole database, which is not what I want.
Yes, it's possible. The steps are the following:
Right click on your Models folder.
Select Add -> Add new Item
In the Add New Item Window, select Data -> ADO.NET Entity Data Model. (This would create a new DbContext, but we going to merge the two DbContext) Click Add
In the Entity Data Model Wizard select Code First from database.
Select your connection String.
Click in no, exclude sensitive data...
Uncheck Save connection settings.
Click next
Select the new Table
Click finish
In this point VS would generate two files: a new DbContext and the model for the table.
Now open de new DbContext cut the DbSet of your model and paste in your original DBContext, too cut the content of the OnModelCreating method and paste at the end of the OnModelCreating method of your Original DbContext.
The final step is add a new Migration ignoring the changes.
For example:
Add-migration NewTableAdded -IgnoreChanges -verbose
Question regarding Core Data migrations:
The original model was just a single entity (Transaction) with multiple properties. The app could store N Transactions, and display them in a table.
Original Core Data Model (simplified):
Transaction:
property_x
property_y
property_z
The model has now been changed so that the new top-level entity is a TransactionsList entity, with a 1-to-many relationship so that each TransactionsList has multiple Transactions.
New Core Data Model (simplified):
TransactionsList:
property_a
property_b
transactions <-->> Transaction:
property_x
property_y
property_z
<- transactionList
The model has now been changed so that the top-level entity is a TransactionsList entity, with a 1-to-many relationship (transactions) so that each TransactionsList has multiple Transactions.
I'm having a problem finding any examples (either in Apple docs, or on the web) of how to set up a migration from the original configuration to this new configuration.
Lightweight migrations don't seem to work (since this change involves adding a new relationship).
I set up a mapping file, and tried to create a custom migration policy, but if I set breakpoints on any of the functions in it, they are never hit.
I turned on migration debugging, and it indicates that the migration succeeded:
"Automatic schema migration succeeded for store at "..."
However, if I look at the internals of the sqlite database, there are no database entries for the TransactionsList entity, and all the transactionList fields in the Transactions (which should be linked to the owning TransactionsList) are null.
Two questions...
1) Any clues as to why my custom entity migration policy might not be getting called
2) Any suggestions on the best way to set up this kind of migration?
Thanks.
You are correct that a light-weight migration will not work. Further, a heavy migration would be very expensive computationally and I would not advise it.
I recommend a two step approach:
Allow a light-weight migration to occur. This will cause your TransactionList entity to be empty.
After the migration, walk through your transactions and create TransactionList entities as appropriate.
This will be faster and easier to test/debug than using a heavy migration. You can test to see if a migration needs to occur using the -[NSManagedObjectModel isConfiguration: compatibleWithStoreMetadata:] method. This will let you know a migration is needed, then you kick off the migration and finally do the post processing.
I am learning code first and I have project to be used with an existing database.
I am a bit confused of what I meant to be doing.I will explain:
Do I need to create an entityconfiguration for each table in my existing database?
Within this EntityConfiguration for each table do I need to create foreign key relationships?
Do I need to do a ToTable for each table in my existing database?
Is there any free tool "codeplex" that pointing to an existing db will generate this codeFirst stuff?
I have seem few blogs about "EF Code first with existing db" but I am not sure or was not clear to me If Need to create this stuff or I will be getting strange errors like "MyColumn_MyColum" basically as if codeFirst is trying to build some FKs or something.
can somebody clarify?
thanks a lot. I know there are few questions but if you can answer 01 or 2 that would be fine.
thanks again
If you want the code to be generated for you use database-first approach with DbContext API. Simply create EDMX file from your database and let DbContext Generator template generate all entities and context for you.
DbContext Fluent API is mainly targeted to the code-first development approach where EF will created database for you from the code you provided. It can be used with existing database but it requires much more skills and understanding of mapping wich EF can provide to you.
Generally:
You don't need to provide EntityConfiguration for each table if you follow some naming conventions (entity name is singular form of table name, all properties have the same name, primary key in table and entity is named as Id or EntityNameId, etc.).
You don't need to define relationships manually if you follow conventions with exposing navigation properties and possibly also foreign key properties. The issue can be naming of many-to-many keys and junction tables.
ToTable is needed only if your entity does not follow naming convention or if you map some advance inheritance or splitting.
EF uses a lot of default conventions which drive how the names should be defined. Conventions can be removed.
You will not do anything wrong if you define EntityConfiguration for each table - it will at least allow you learning what is needed and your mapping will be explicit / self documented.
I have a single hosted SQL Server DB and I don't have permissions to drop it. How do I make EF create tables from my domain classes? RecreateDatabaseIfModelChanges and AlwaysRecreateDatabase try to drop DB, CreateDatabaseOnlyIfNotExists doesn't create the tables.
Thx
CreateDatabaseOnlyIfNotExists is the default strategy. It means you don't need to even set it through the Database.SetInitializer. EF Code First will check the database and if couldn't find one with the same name as your context's fully qualified name, it will create one for you.