Search code examples
c#entity-framework-coreef-database-first

Scaffold-DbContext breaking change upgrading from EF Core 6 to EF Core 7


I have an entity framework model that I generated from a Postgres Database(database first) using Scaffold-DbContext for Entity Framework Core 6

The command I used to generate my model is:

Scaffold-DbContext "ConnexionString" Npgsql.EntityFrameworkCore.PostgreSQL -Context MyDBContext -Force

Now, I want to upgrade to Entity Framework Core 7. So I run the same query

The models I got are different : the relationships are now read only :

property generated with EF Core 6 : public virtual ICollection<Utilisateur> Relation1 { get; set; }

property generated with EF Core 7 : public virtual ICollection<Utilisateur> Relation1 { get; } = new List<Utilisateur>();

I couldn't find any documentation for this change

  • Was this change intended ? I find it weird that the relationships are read only. I should be able to add a child entity
  • Is there a way around it ? (I know that I can always use the hacky solution myEntity.Relation1.ToList().AddRange(aNewList) but that does not seam right)

Solution

  • Update : I regenerated my entities using EF 7.0.5 (without any customization) and now the setters are back again. So no need to customize the scaffolding for this


    Like noted in the comments and in the linked thread, no one seems to understand the reasons behind this undocumented change. But if needed, here's how to make your collections mutable (I'll copy the response from the linked thread. I tried the steps below using EF Core 7.0.3)

    You can customize the scaffolding since .NET 7 using Custom Reverse Engineering Templates.

    1. In visual studio, open the Package manager console

    2. As a default project, select the project from where you will generate your entities/context (Generally, it will be your Data Access Layer project). Let's call it DalProject

    3. Place yourself under DalProject : cd .\DalProject

    4. Install the required templates: dotnet new install Microsoft.EntityFrameworkCore.Templates

    5. Generate the template files : dotnet new ef-templates

    This will generate a folder named CodeTemplates that contains a folder named EFCore that contains 2 files DbContext.t4 and EntityType.t4 inside your DalProject

    1. Update EntityType.t4 file so that all collection navigations will be settable (find all ICollection mentions in the file). In my case, I found it in 2 places :

    here :

    if (navigation.IsCollection)
    {
    #>
        public virtual ICollection<<#= targetType #>> <#= navigation.Name #> { get; set; } = new List<<#= targetType #>>();
    <#
    

    and here :

    #>
        public virtual ICollection<<#= skipNavigation.TargetEntityType.Name #>> <#= skipNavigation.Name #> { get; } = new List<<#= skipNavigation.TargetEntityType.Name #>>();
    <#