Entity Framework Core Database-First Update after initial Scaffold?
Asked Answered
S

3

14

I'm playing around with Entity Framework Core and I have been working on implementing a Database-First application. The initial Scaffold-DbContext command works just fine and creates all my entities correctly, if not organized as I would like. It's a SQL Server database that uses schemas to break up areas of responsibility and I don't really care for the fact that the Scaffold just throws them all into a single folder.

That aside, I have been unable to determine if there is a way to re-run the Scaffold to update the classes after a database update has occurred. The closest I can find is to re-run the Scaffold-DbContext command with the -force parameter. However, this also overwrites any custom code I have added to the Context.cs file, like pointing the connection string to a config value instead of hard-coding.

I have looked at a couple other questions similiar to this one, but it only talks about the initial scaffold, not further updates.

Is there a way short of manually coding any future changes to do this? Without that it seems to make a database-first approach utterly worthless with EF Core.

Shipboard answered 31/10, 2016 at 14:43 Comment(1)
For your schema comment you may want to try something like this where 'integration' is the name of the schema: dotnet ef dbcontext scaffold "<ConnectionString>" Microsoft.EntityFrameworkCore.SqlServer -c "IntegrationContext" --schema "integration" -fMikey
S
12

Like you said yourself... The main problem with database first approach : You should never change the model manually and start renaming things etc. Except if you are 100 % sure that your database won't change anymore. If you'r not 100 % sure, just code with the model that has been auto-generated.

Re-Scaffolding will overwrite any changes made directly in the model class, erasing all what you have changed or added.

But you can make partial classes on the side that won't be overwritten by auto mapping :

public partial class TableName
{
    public string Name_of_a_property
    {get; set;}
}

It's a nice way to add code to your entity while being sure it won't be touched by auto-mapping. Just make sure the partial view has the same name as the auto-generated class and everything should be OK.

Stellate answered 31/10, 2016 at 15:53 Comment(5)
Of course, with it being Monday, the partial classes didn't enter my head. I abandoned EF after using EF5 for a while. Completely forgot about that approach. This will work. Just gotta remember to re-scaffold after any database updates.Shipboard
I do not understand how doing this helps. I believe you. I just don't know how to do it. When I first generate my classes from the database, when do I do the partial class and where? Then rescaffold?Aurelie
@Aurelie You can just add a new class to your project, and strangely, by naming the partial class the SAME name as your table will make them see each other, you can use extra functions you coded in partial class. While the table class might change on re-scaffold, never will the partial class. Code as much as you want in the partial classes, not directly in the model classes. This goes only for DB first. (i hope it make better sens)Stellate
@AntoinePelletier Here is an interesting link about an Update-Scaffold command which apparently just hadn't made it into the 3.0 release: github.com/aspnet/EntityFrameworkCore/issues/831Navarro
@DanChase Yes there are some other tricks to make this happen without partial class. People will choose what they think is the best for them in a database first approach. And the answer under mine is also good. Should I edit mine to include more possibilities ? Also, if you feel like it, you can edit my answer to include this other method you found.Stellate
T
4

Re-runnable scaffold can be used for true DB First approach as answered by Antoine Pelletier.

However more often scaffold is used once for initial import of the model to your code, and then continue with the Code First approach. The process to use reverse engineering to create an Entity Framework model based on an existing database described in https://learn.microsoft.com/en-us/ef/core/get-started/aspnetcore/existing-db

Traveller answered 12/11, 2017 at 9:29 Comment(4)
Yes, but it sure does seem to cause (me) a lot of headache when I do that. I had the same thoughts, but in my practice it gets hard to do because I have to go and start messing with the context.cs as well as my generated classes. Say if I add a Foreign Key or something.Aurelie
@johnny, Code First assumes that you consider context and entity classes not as generated, but as master model. Your changes will be done in code, and then apply to DB via migrations. However I agree, that sometimes it can be tricky. You can run embedded scripts for some sql changes, such as adding extra indexesTraveller
@MiFreidgeimSO-stopbeingevil what do you do if DBA's require you submit DDL changes? We have to refresh our dev environments from prod every once in a while, and I'm entirely confused about Code First in a real world scenario.Navarro
@DanChase, not sure, that fully understand your situation. Either explain to DBA, that in Code First DDL are deployed as part of code deployment, or do not use Code First. Better raise a new question with more details to allow someone else to answer it.Traveller
G
0

Use same Scaffold command with an extra attribute -f

Scaffold-DbContext "Server=(localdb)\MSSQLLocalDB;Database=ProductDB;Trusted_Connection=True;" Microsoft.EntityFrameworkCore.SqlServer -OutputDir Models -f

Here -f means -force.

Gamali answered 10/12, 2023 at 18:52 Comment(1)
OP mentions -f switch. It has been there forever; not new in .NET 8.Fiducial

© 2022 - 2024 — McMap. All rights reserved.