问题是,EF核心正在为多到多的关系创建额外的外键列,尽管我已经指定了外键是什么。
我有以下实体模型,它们需要处于多到多的关系中。
ParticipantModel.cs
public class ParticipantModel
{
public int Id { get; set; }
public HashSet<ThreadsParticipants> ThreadsParticipants { get; set; } = new HashSet<ThreadsParticipants>();
}ThreadModel.cs
public class ThreadModel
{
public int Id { get; private set; }
public HashSet<ThreadsParticipants> ThreadsParticipants { get; set; } = new HashSet<ThreadsParticipants>();
}ThreadsParticipants.cs (连接表)
public class ThreadsParticipants
{
public int ThreadModelId { get; private set; }
public ThreadModel ThreadModel { get; private set; } = default!;
public int ParticipantModelId { get; private set; }
public ParticipantModel ParticipantModel { get; private set; } = default!;
}以及以下配置EntityTypeConfiguration:
public void Configure(EntityTypeBuilder<ParticipantModel> builder)
{
builder.HasKey(p => p.Id);
}
public void Configure(EntityTypeBuilder<ThreadModel> builder)
{
builder.HasKey(t => t.Id);
}
public void Configure(EntityTypeBuilder<ThreadsParticipants> builder)
{
builder
.HasKey(tp => new { tp.ThreadModelId, tp.ParticipantModelId });
builder
.HasOne(tp => tp.ThreadModel)
.WithMany()
.HasForeignKey(tp => tp.ThreadModelId)
.IsRequired();
builder
.HasOne(tp => tp.ParticipantModel)
.WithMany()
.HasForeignKey(tp => tp.ParticipantModelId)
.IsRequired();
}在运行add-migration时,生成创建ThreadsParticipants表的块如下:
migrationBuilder.CreateTable(
name: "MessageThreadsParticipants",
columns: table => new
{
ThreadModelId = table.Column<int>(nullable: false),
ParticipantModelId = table.Column<int>(nullable: false),
ParticipantModelId1 = table.Column<int>(nullable: true),
ThreadModelId1 = table.Column<int>(nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_MessageThreadsParticipants", x => new { x.ThreadModelId, x.ParticipantModelId });
table.ForeignKey(
name: "FK_MessageThreadsParticipants_MessageParticipants_ParticipantModelId",
column: x => x.ParticipantModelId,
principalTable: "MessageParticipants",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_MessageThreadsParticipants_MessageParticipants_ParticipantModelId1",
column: x => x.ParticipantModelId1,
principalTable: "MessageParticipants",
principalColumn: "Id",
onDelete: ReferentialAction.Restrict);
table.ForeignKey(
name: "FK_MessageThreadsParticipants_MessageThreads_ThreadModelId",
column: x => x.ThreadModelId,
principalTable: "MessageThreads",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_MessageThreadsParticipants_MessageThreads_ThreadModelId1",
column: x => x.ThreadModelId1,
principalTable: "MessageThreads",
principalColumn: "Id",
onDelete: ReferentialAction.Restrict);
});当我明确指定外键是什么时,为什么会生成这些额外的外键属性?
发布于 2020-08-04 11:18:06
编辑
正如@Flater的注释所示,原因是配置被指定了两次,因此创建了一组额外的列。
实际上,从ThreadsParticipants实体类型配置中删除双工一对多的Fluent API配置解决了这个问题,并且不再创建额外的属性。当删除配置的这一部分时,EF使用命名传送来显示关系,因此没有必要显式地声明关系细节。
builder
.HasOne(tp => tp.ThreadModel)
.WithMany()
.HasForeignKey(tp => tp.ThreadModelId)
.IsRequired();
builder
.HasOne(tp => tp.ParticipantModel)
.WithMany()
.HasForeignKey(tp => tp.ParticipantModelId)
.IsRequired();这使我认为,有一个财产名称不匹配,正在引起所有的麻烦。
发布于 2020-08-04 12:12:52
事情是这样的,您有一组外键,它们也用作该表的复合键。实体框架必须找到解决命名争议的方法。您可以将数据注释显式地添加到模型中,以抑制此问题。
[ForeignKey("ThreadModel")]
public int ThreadModelId { get; private set; }还有其他财产
为什么不通过添加
//...
.WithMany(x => x.ThreadsParticipants)
//...https://stackoverflow.com/questions/63245591
复制相似问题