I have the following data model:
public class Foo
{
public Foo(int barId)
{
BarId = barId;
}
private int BarId;
public Bar Bar { get; private set; }
}
public class FooTypeConfig : IEntityTypeConfiguration<Foo>
{
public void Configure(EntityTypeBuilder<Foo> builder)
{
builder.HasOne(x => x.Bar)
.WithMany()
.HasForeignKey("BarId");
}
}
public class Bar
{
public int Id { get; private set; }
}
This works great and according to my expectations, I have a Foo
table containing Id
and BarId
. My private field BarId
and my Bar
property are also correctly materialized when reading Foo
from the database.
The problem is that I would like to find a way to name my private field, and choose a different name for my database column. I would like to name my property _barId
and still choose BarId
as my column name in my database.
Is this possible?
I have tried renaming the field in my Foo
class and specifying my (now non-conventionally-named) foreign key _barId
in my EntityTypeConfiguration
builder.HasOne(x => x.Bar).WithMany().HasForeignKey("_barId");
But this resulted in EF still generating a BarId
column, without using it as foreign key to the Bar
table...
migrationBuilder.CreateTable(
name: "Foos",
columns: table => new
{
Id = table.Column<int>(nullable: false)
.Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
BarId = table.Column<int>(nullable: true),
_barId = table.Column<int>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Foos", x => x.Id);
table.ForeignKey(
name: "FK_Foos_Bars__barId",
column: x => x._barId,
principalTable: "Bars",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
First off, EF maps database columns and FKs to entity properties, not fields. The properties can be real or as in your case - shadow.
So the following line:
builder.HasOne(x => x.Bar).WithMany().HasForeignKey("BarId");
maps the Bar
-> Foo
relationship FK to a Foo
shadow property called BarId
and should stay as it is.
You use the Property
method to configure the property type, backing field, column name, type and other attributes. For instance:
builder.Property<int>("BarId") // or int? etc.
.HasField("_barId")
.HasColumnName("BarId"); // or BazId or whatever you like
Just make sure you use one and the same property name when defining it and when specifying the FK. You can also use Entry(entity).Property(propertyName)
to get/set the value, mark it as modified etc. as well as EF.Property(entity, propertyName
) to access it inside LINQ to Entities queries.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With