Skip to content

Setting entity/property name via IEntityTypeAddedConvention breaks migration #35330

Open
@grosch-intl

Description

Ask a question

When I run an initial migration, everything works without issue, and the many-to-many table relationship you auto-generated below appears in the migration. However, if I try to use an IEntityTypeAddedConvention to make things snake case, the migration aborts.

Include your code

internal partial class RandomEntityTypeConvention : IEntityTypeAddedConvention
{
    private static readonly Regex UpperCaseRegex = AutoGeneratedRegex();

    [GeneratedRegex("([a-z0-9])([A-Z])", RegexOptions.Compiled | RegexOptions.ExplicitCapture, matchTimeoutMilliseconds: 1000)]
    private static partial Regex AutoGeneratedRegex();

    private static string ToSnakeCase(string name) => UpperCaseRegex.Replace(name, "$1_$2").ToLowerInvariant();

    #region IEntityTypeAddedConvention implementation
    public void ProcessEntityTypeAdded(IConventionEntityTypeBuilder entityTypeBuilder, IConventionContext<IConventionEntityTypeBuilder> context) {
        var entityType = entityTypeBuilder.Metadata;

        var name = entityType.ClrType.Name;
        entityType.SetTableName(ToSnakeCase(name));

        foreach (var property in entityType.GetProperties())
            property.SetColumnName(ToSnakeCase(property.Name));
    }
    #endregion
}

Failure message from migration

Unable to create a 'DbContext' of type 'SdcDatabaseContext'. The exception 'Cannot use table 'dictionary2' for entity type 'ExportControlClassificationNumberSoftwarePackage (Dictionary<string, object>)' since it is being used for entity type 'DistributionFileSoftwarePackage (Dictionary<string, object>)' and potentially other entity types, but there is no linking relationship. Add a foreign key to 'ExportControlClassificationNumberSoftwarePackage (Dictionary<string, object>)' on the primary key properties and pointing to the primary key on another entity type mapped to 'dictionary2'.' was thrown while attempting to create an instance. For the different patterns supported at design time, see https://go.microsoft.com/fwlink/?linkid=851728

Good code you generate if I don't add the convention

migrationBuilder.CreateTable(
    name: "ExportControlClassificationNumberSoftwarePackage",
    columns: table => new
    {
        ExportControlClassificationNumbersId = table.Column<int>(type: "integer", nullable: false),
        SoftwarePackagesId = table.Column<int>(type: "integer", nullable: false)
    },
    constraints: table =>
    {
        table.PrimaryKey("PK_ExportControlClassificationNumberSoftwarePackage", x => new { x.ExportControlClassificationNumbersId, x.SoftwarePackagesId });
        table.ForeignKey(
            name: "FK_ExportControlClassificationNumberSoftwarePackage_ExportCont~",
            column: x => x.ExportControlClassificationNumbersId,
            principalTable: "ExportControlClassificationNumber",
            principalColumn: "Id",
            onDelete: ReferentialAction.Cascade);
        table.ForeignKey(
            name: "FK_ExportControlClassificationNumberSoftwarePackage_SoftwarePa~",
            column: x => x.SoftwarePackagesId,
            principalTable: "SoftwarePackage",
            principalColumn: "Id",
            onDelete: ReferentialAction.Cascade);
    });

Include provider and version information

EF Core version: 9.0.0
Database provider: Npgsql.EntityFrameworkCore.PostgreSQL 9.0.1
Target framework: .NET 9
Operating system: Windows 11
IDE: Visual Studio 2022 17.12.3

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions