首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >EntityFramework Core3.0 Fluent API多到多关系生成器创建额外的外键列

问EntityFramework Core3.0 Fluent API多到多关系生成器创建额外的外键列
EN

Stack Overflow用户
提问于 2020-08-04 11:08:04
回答 2查看 131关注 0票数 0

问题是,EF核心正在为多到多的关系创建额外的外键列,尽管我已经指定了外键是什么。

我有以下实体模型,它们需要处于多到多的关系中。

ParticipantModel.cs

代码语言:javascript
复制
public class ParticipantModel
{
    public int Id { get; set; }

    public HashSet<ThreadsParticipants> ThreadsParticipants { get; set; } = new HashSet<ThreadsParticipants>();
}

ThreadModel.cs

代码语言:javascript
复制
public class ThreadModel
{
    public int Id { get; private set; }

    public HashSet<ThreadsParticipants> ThreadsParticipants { get; set; } = new HashSet<ThreadsParticipants>();
}

ThreadsParticipants.cs (连接表)

代码语言:javascript
复制
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:

代码语言:javascript
复制
    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表的块如下:

代码语言:javascript
复制
            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);
            });

当我明确指定外键是什么时,为什么会生成这些额外的外键属性?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-08-04 11:18:06

编辑

正如@Flater的注释所示,原因是配置被指定了两次,因此创建了一组额外的列。

实际上,从ThreadsParticipants实体类型配置中删除双工一对多的Fluent API配置解决了这个问题,并且不再创建额外的属性。当删除配置的这一部分时,EF使用命名传送来显示关系,因此没有必要显式地声明关系细节。

代码语言:javascript
复制
    builder
        .HasOne(tp => tp.ThreadModel)
        .WithMany()
        .HasForeignKey(tp => tp.ThreadModelId)
        .IsRequired();

    builder
        .HasOne(tp => tp.ParticipantModel)
        .WithMany()
        .HasForeignKey(tp => tp.ParticipantModelId)
        .IsRequired();

这使我认为,有一个财产名称不匹配,正在引起所有的麻烦。

票数 1
EN

Stack Overflow用户

发布于 2020-08-04 12:12:52

事情是这样的,您有一组外键,它们也用作该表的复合键。实体框架必须找到解决命名争议的方法。您可以将数据注释显式地添加到模型中,以抑制此问题。

代码语言:javascript
复制
[ForeignKey("ThreadModel")]
public int ThreadModelId { get; private set; }

还有其他财产

为什么不通过添加

代码语言:javascript
复制
//...
.WithMany(x => x.ThreadsParticipants)
//...
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63245591

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档