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
myEntity.Relation1.ToList().AddRange(aNewList)
but that does not seam right)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.
In visual studio, open the Package manager console
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
Place yourself under DalProject
: cd .\DalProject
Install the required templates: dotnet new install Microsoft.EntityFrameworkCore.Templates
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
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 #>>();
<#