Reputation: 545
I'm currently using the Npgsql provider with EF Core 2.0 in an ASP.NET Core application.
I've converted all table/column/relationship names to snake case in order to fit the Postgres convention and to make it easier to write native statements in code.
The migrations for this generate fine, but the owned type primary key isn't recorded in the ModelSnapshot, so every time I generate a new migration, it attempts to rename the PK from PK_foo to pk_foo, even though it already is pk_foo in the database itself. This migration will obviously fail unless the offending line is removed.
Is there any way to override this? Or would the workaround be to make it not an owned entity?
This is the partial OnModelCreating code:
builder.Entity<Foo>()
.OwnsOne(t => t.Bar)
.ToTable("bar")
.OnDelete(DeleteBehavior.Cascade);
foreach (var entity in builder.Model.GetEntityTypes())
{
entity.Relational().TableName = entity.Relational().TableName.ToSnakeCase();
foreach (var property in entity.GetProperties())
{
property.Relational().ColumnName = property.Name.ToSnakeCase();
}
foreach (var key in entity.GetKeys())
{
key.Relational().Name = key.Relational().Name.ToSnakeCase();
}
foreach (var key in entity.GetForeignKeys())
{
key.Relational().Name = key.Relational().Name.ToSnakeCase();
}
foreach (var index in entity.GetIndexes())
{
index.Relational().Name = index.Relational().Name.ToSnakeCase();
}
}
This is the migration created:
migrationBuilder.CreateTable(
name: "bar",
columns: table => new
{
foo_id = table.Column<int>(nullable: false),
data = table.Column<byte[]>(nullable: true)
},
constraints: table =>
{
table.PrimaryKey("pk_bar", x => x.foo_id);
table.ForeignKey(
name: "fk_bar_foo_foo_id",
column: x => x.foo_id,
principalTable: "foo",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
});
This is the relevant part of the model snapshot
modelBuilder.Entity("ExampleProject.Foo", b =>
{
b.OwnsOne("ExampleProject.Bar", "Bar", b1 =>
{
b1.Property<int>("FooId")
.HasColumnName("foo_id");
b1.Property<byte[]>("Data")
.HasColumnName("data");
b1.ToTable("bar");
b1.HasOne("ExampleProject.Foo")
.WithOne("Bar")
.HasForeignKey("ExampleProject.Bar", "FooId")
.HasConstraintName("fk_bar_foo_foo_id")
.OnDelete(DeleteBehavior.Cascade);
});
});
EF Core version: 2.0 Database Provider: Npgsql Operating system: Windows 10 IDE: Visual Studio 2017 15.3.4
Upvotes: 2
Views: 528
Reputation: 1
As commented by @Brice Lambson. There's no way to address the primary key name from the ModelBuilder API.
The only way I can see to configure it is to drop down to metadata:
b1.Metadata.DeclaringEntityType
.GetOrSetPrimaryKey(b1.Property("FooId").Metadata)
.Relational().Name = "pk_bar";
The issue has been added to Backlog.
Upvotes: 0