Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Document scaffolded navigation breaking change #4608

Closed
shikamu opened this issue Dec 28, 2023 · 4 comments · Fixed by #4673
Closed

Document scaffolded navigation breaking change #4608

shikamu opened this issue Dec 28, 2023 · 4 comments · Fixed by #4673

Comments

@shikamu
Copy link

shikamu commented Dec 28, 2023

I'm working on a asp.net core backend that was on .net 6 and we're trying to migrate it to .net 8.

We have noticed a change for which we haven't yet found documentation. Given a simple Test database with the following 3 tables:

CREATE TABLE [dbo].[ItemCategory] (
    [Name]                 VARCHAR (25)     NOT NULL,
    [Description]          NVARCHAR (512)   NULL,
    CONSTRAINT [PK_ItemCategory] PRIMARY KEY CLUSTERED ([Name] ASC),
);

CREATE TABLE [dbo].[Item] (
    [Name]                   VARCHAR (40)     NOT NULL,
    [Description]            NVARCHAR (512)   NULL,
    [CategoryName]           VARCHAR (25)     NOT NULL,
    CONSTRAINT [PK_Item] PRIMARY KEY CLUSTERED ([Name] ASC, [CategoryName] ASC),
    CONSTRAINT [FK_Item_ItemCategory] FOREIGN KEY ([CategoryName]) REFERENCES [dbo].[ItemCategory] ([Name]),
);

CREATE TABLE [dbo].[SomeTable] (
    [Id]                   INT              IDENTITY (1, 1) NOT FOR REPLICATION NOT NULL,
    [DetailItemName]         VARCHAR (40) NOT NULL,
    [DetailItemCategoryName] VARCHAR (25) NOT NULL,
    CONSTRAINT [PK_SomeTable] PRIMARY KEY CLUSTERED ([Id] ASC),
    CONSTRAINT [FK_SomeTable_DetailItem] FOREIGN KEY ([DetailItemName], [DetailItemCategoryName]) REFERENCES [dbo].[Item] ([Name], [CategoryName])
);

I can use the following command to generate the c# classes:

dotnet ef dbcontext scaffold "Data Source=localhost\sqlexpress;Initial Catalog=Test;Integrated Security=True;MultipleActiveResultSets=True;TrustServerCertificate=True" Microsoft.EntityFrameworkCore.SqlServer -f

if I use net6.0, namely with exactly this csproj:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>net6.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="6.0.25">
      <PrivateAssets>all</PrivateAssets>
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
    </PackageReference>
    <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="6.0.25" />
  </ItemGroup>

  <ItemGroup>
    <Folder Include="Models\" />
  </ItemGroup>

</Project>

I get the following output for the SomeTable C# class:

using System;
using System.Collections.Generic;

namespace ClassLibrary1
{
    public partial class SomeTable
    {
        public int Id { get; set; }
        public string DetailItemName { get; set; } = null!;
        public string DetailItemCategoryName { get; set; } = null!;

        public virtual Item DetailItem { get; set; } = null!;
    }
}

However, if I switch to net8.0, using exactly this csproj:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>net8.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.0">
      <PrivateAssets>all</PrivateAssets>
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
    </PackageReference>
    <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="8.0.0" />
  </ItemGroup>

  <ItemGroup>
    <Folder Include="Models\" />
  </ItemGroup>

</Project>

I get the following output:

using System;
using System.Collections.Generic;

namespace ClassLibrary1;

public partial class SomeTable
{
    public int Id { get; set; }

    public string DetailItemName { get; set; } = null!;

    public string DetailItemCategoryName { get; set; } = null!;

    public virtual Item Item { get; set; } = null!;
}

Notice that with net6.0 and net7.0 we get this:

        public virtual Item DetailItem { get; set; } = null!;

but with net8.0 we get this:

    public virtual Item Item { get; set; } = null!;

When I run the scaffold command in both cases I get the same output in both cases:
image

We have a lot of existing code and tables and we'd like to be able to use the "old naming scheme" if possible. Is there a way to do that ?

Thanks!

@ajcvickers
Copy link
Member

Note for triage: this is a consequence of dotnet/efcore#29771, which stopped using common prefixes to generate navigation names.

@shikamu Custom T4 templates can be used to customize the navigation names to whatever you choose.

@ajcvickers
Copy link
Member

Note from triage: the new behavior is preferable to the old behavior, but for cases where the old behavior was reasonable we should document this as a breaking change.

@ajcvickers ajcvickers transferred this issue from dotnet/efcore Jan 4, 2024
@ajcvickers ajcvickers self-assigned this Jan 4, 2024
@ajcvickers ajcvickers added this to the Backlog milestone Jan 4, 2024
@shikamu
Copy link
Author

shikamu commented Jan 4, 2024

@ajcvickers thanks for the replies. Is there a ready to use T4 template that emulates the old behaviour ? this would be quite useful to have as this is essentially a breaking change, and we would then be able to get around it in an effortless fashion.

@ajcvickers
Copy link
Member

@shikamu There is no specific template for this. Start from the default templates and edit the code that writes the navigation names.

@ajcvickers ajcvickers modified the milestones: Backlog, 9.0.0 Mar 9, 2024
@ajcvickers ajcvickers changed the title scaffolding change in the name of navigation property since dotnet 8.0 ? Document scaffolded navigation breaking change Mar 9, 2024
ajcvickers added a commit that referenced this issue Mar 10, 2024
Fixes #4608
Part of #4538
Fixes #4315
Fixes #4257
Fixes #4655
Fixes #4654
ajcvickers added a commit that referenced this issue Mar 10, 2024
Fixes #4608
Part of #4538
Fixes #4315
Fixes #4257
Fixes #4655
Fixes #4654
ajcvickers added a commit that referenced this issue Mar 10, 2024
* Updates to breaking changes

Fixes #4608
Part of #4538
Fixes #4315
Fixes #4257
Fixes #4655
Fixes #4654

* Update entity-framework/core/what-is-new/ef-core-6.0/breaking-changes.md

Co-authored-by: Shay Rojansky <roji@roji.org>

* Updates

---------

Co-authored-by: Shay Rojansky <roji@roji.org>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants