I have two Objects in a one-to-many relation: User on the many and DBConnector on the one side.
- Users primary Key is
Username
. - DBConnectors primary Key is
DBConnectorId
. - DBConnector has a separate, unrelated field
UserId
.
When creating the model with EF, EF does not create a separate column Username
on DBConnector and instead repurposes UserId
as foreign Key for the one-to-many relation, thus omitting the assigned values for the actual UserId
field. (Which are instead replaced with the foreign key value of Users)
Below the two classes, the OnModelCreating and the created Migration.
DBConnector.cs
[PrimaryKey("DBConnectorId")]
public abstract class DBConnector(string userId, [...])
{
[StringLength(64)]
[Required]
public string DBConnectorId { get; init; } = KeyHelper.CreateRandomKey(64);
[StringLength(64)]
[Required]
public string UserId { get; init; } = userId;
[...]
}
User.cs
[PrimaryKey("Username")]
public class User(string username, [...])
{
[StringLength(64)]
[Required]
public string Username { get; internal set; } = username;
[StringLength(64)]
[Required]
[NotMapped]
public string[] ConnectionIds => Connections.Select(c => c.DBConnectorId).ToArray();
[Required]
[JsonIgnore]
public Collection<DBConnector.DBConnector> Connections { get; internal set; } = [];
[...]
}
OnModelCreating
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<User>()
.HasMany<DBConnector.DBConnector>(u => u.Connections)
.WithOne()
.OnDelete(DeleteBehavior.Cascade);
modelBuilder.Entity<User>()
.Navigation(u => u.Connections)
.AutoInclude();
[...]
}
EF-Autogenerated Migration
migrationBuilder.CreateTable(
name: "DBConnectors",
columns: table => new
{
DBConnectorId = table.Column<string>(type: "TEXT", maxLength: 64, nullable: false),
UserId = table.Column<string>(type: "TEXT", maxLength: 64, nullable: false),
[...]
},
constraints: table =>
{
table.PrimaryKey("PK_DBConnectors", x => x.DBConnectorId);
table.ForeignKey(
name: "FK_DBConnectors_Users_UserId",
column: x => x.UserId,
principalTable: "Users",
principalColumn: "Username",
onDelete: ReferentialAction.Cascade);
});
When I change the DBConnector field UserId
to anything else (say DatabaseUser
), it creates a separate column as expected.
Is this a configuration-option somewhere or effect of some naming-standard that I am missing? On all other relations which involve User, the foreign-key-column is named Username
.