Setting entity/property name via IEntityTypeAddedConvention breaks migration
grosch-intl opened this issue · 3 comments
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 'dictionary
2' 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 'dictionary
2'.' 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
If I instead do this via OnModelCreating
by looping through modelBuilder.Model.GetEntityTypes()
then it doesn't fail.