dotnet / efcore

EF Core is a modern object-database mapper for .NET. It supports LINQ queries, change tracking, updates, and schema migrations.
https://docs.microsoft.com/ef/
MIT License
13.8k stars 3.19k forks source link

Scaffolded collection navigation properties do not have setters #30286

Closed giarico closed 1 year ago

giarico commented 1 year ago

Hello,

With EF7 all child entities are get only collections. If I use the generated entities for deserialization, the child entities remain null.

Example of an entity with a child collection. Before EF7 it was get & set.

public partial class ComplaintType
{
    ...

    [InverseProperty("ComplaintType")]
    public virtual ICollection<LocalizedComplaintType> LocalizedComplaintTypes { get; } = new List<LocalizedComplaintType>();
}

When I try to deserialize the returned json to the ComplaintType object, the LocalizedComplaintTypes property is null return await httpClient.GetFromJsonAsync<IEnumerable<ComplaintType>>(...);

If I modify the ComplaintType class putting set or init on LocalizedComplaintTypes property, it works.

Why this change in EF7? I had a lot of drawbacks... and not limited to this. What is the workaround?

ajcvickers commented 1 year ago

Note for triage: it's unfortunate that this prevents the collection from being serialized, at least in System.Text.Json. We should consider adding the setter back because of this.

@giarico You can customize the T4 template to create setters.

ErikEJ commented 1 year ago

Thanks, @ajcvickers - I will add this as default in the next version of the templates supplied with EF Core Power Tools

ajcvickers commented 1 year ago

Note from triage: we will change the default back to collections with setters, and take this to Tactics for a 7.0.x patch.

jmoralesv commented 1 year ago

Hello! I have a question: do you know if this will be available in version 7.0.4 on the second Tuesday of March 2023, or at a later date? I have a project that relies on the setter to be available, and having this back would be great.

Thanks!

ErikEJ commented 1 year ago

@jmoralesv you can use EF Core Power Tools with T4 templates today or use your own t4 template.

ajcvickers commented 1 year ago

@jmoralesv This will be in the 7.0.5 release, as indicated by the milestone.

jmoralesv commented 1 year ago

@ajcvickers thank you! I think it will be available in April 2023, if I'm not mistaken.

Is there a way to have access to the fix through NuGet, so we can test the fix? I can see only a preview for version 8.0 at the moment: https://www.nuget.org/packages/Microsoft.EntityFrameworkCore#versions-body-tab

That way we can have that already fixed in our project, and we can switch to the final release version once it is available in April.

Thanks!

janseris commented 1 year ago

I have updated to EF Core 7.0.5 and regenerated the code using EF Core Power Tools but the collection still only has getter. @ErikEJ Is there an update required to be released in EF Core Power tools to include this?

ErikEJ commented 1 year ago

Someone need to update the EF7 Tools in Power Tools to 7.0.5

ErikEJ commented 1 year ago

https://github.com/ErikEJ/EFCorePowerTools/issues/1762

ErikEJ commented 1 year ago

@janseris Fixed in latest daily

fschlaef commented 1 year ago

@ErikEJ this is still an issue today.

Visual Studio 17.6.5 .NET SDK 7.0.306

Command used :

Scaffold-DbContext "Server=server\instance;Database=database;User ID=sa;Password=password;TrustServerCertificate=true;" Microsoft.EntityFrameworkCore.SqlServer -Force -OutputDir Models -NoPluralize -NoOnConfiguring -Schemas dbo -Context DbContext

All my collections look like this, in all my models :

public virtual ICollection<Item> Item { get; } = new List<Item>();

Did I do something wrong ?

Edit : using the T4 templates is still a valid workaround.

ErikEJ commented 1 year ago

@fschlaef Update your Tools package?

fschlaef commented 1 year ago

@fschlaef Update your Tools package?

Okay, this is embarrassing ... I updated the packages but I messed up somewhere and the .csproj wasn't saved, so I was using 7.0.3.

After properly updating to 7.0.9, it is indeed working correctly and T4 templates are no longer required.

Thank you @ErikEJ for the help !