首页 > 解决方案 > 具有显式映射表和与流式 API 的显式关系的 EF Core 5 导致迁移中映射表中的附加外键

问题描述

将 EF Core 5 与显式映射表以及与流式 API 的显式关系一起使用会导致迁移中映射表中出现额外的外键。

使用 Microsoft.EntityFrameworkCore.SqlServer Version="5.0.7" 和

Microsoft.EntityFrameworkCore.Tools 版本="5.0.7"

楷模

    public class ModelA
    {
        public string Id { get; set; }

        public string SomeData { get; set; }

        public IEnumerable<MappingModel> Models { get; set; } = new List<MappingModel>();
    }

    public class ModelB
    {
        public int Id { get; set; }

        public string AnotherData { get; set; }

        public IEnumerable<MappingModel> Models { get; set; } = new List<MappingModel>();
    }

    public class MappingModel
    {
        public string ModelAId { get; set; }

        public ModelA ModelA { get; set; }

        public int ModelBId { get; set; }

        public ModelB ModelB { get; set; }
    }

应用程序数据库上下文

    public class ApplicationDbContext: DbContext
    {
        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<MappingModel>()
                .HasKey(k => new { k.ModelAId, k.ModelBId });

            modelBuilder.Entity<MappingModel>()
                .HasIndex(uc => uc.ModelAId);

            modelBuilder.Entity<MappingModel>()
                .HasIndex(uc => uc.ModelBId);

            modelBuilder.Entity<MappingModel>()
                .HasOne<ModelA>()
                .WithMany(u => u.Models)
                .HasForeignKey(uc => uc.ModelAId)
                .OnDelete(DeleteBehavior.Restrict)
                .IsRequired();

            modelBuilder.Entity<MappingModel>()
                .HasOne<ModelB>()
                .WithMany(c => c.Models)
                .HasForeignKey(uc => uc.ModelBId)
                .OnDelete(DeleteBehavior.Restrict)
                .IsRequired();
        }

为映射表生成的迁移将是

            migrationBuilder.CreateTable(
                name: "MappingModel",
                columns: table => new
                {
                    ModelAId = table.Column<string>(type: "nvarchar(450)", nullable: false),
                    ModelBId = table.Column<int>(type: "int", nullable: false),
                    ModelAId1 = table.Column<string>(type: "nvarchar(450)", nullable: true),
                    ModelBId1 = table.Column<int>(type: "int", nullable: true)
                },
                constraints: table =>
                {
                    table.PrimaryKey("PK_MappingModel", x => new { x.ModelAId, x.ModelBId });
                    table.ForeignKey(
                        name: "FK_MappingModel_ModelA_ModelAId",
                        column: x => x.ModelAId,
                        principalTable: "ModelA",
                        principalColumn: "Id",
                        onDelete: ReferentialAction.Restrict);
                    table.ForeignKey(
                        name: "FK_MappingModel_ModelA_ModelAId1",
                        column: x => x.ModelAId1,
                        principalTable: "ModelA",
                        principalColumn: "Id",
                        onDelete: ReferentialAction.Restrict);
                    table.ForeignKey(
                        name: "FK_MappingModel_ModelB_ModelBId",
                        column: x => x.ModelBId,
                        principalTable: "ModelB",
                        principalColumn: "Id",
                        onDelete: ReferentialAction.Restrict);
                    table.ForeignKey(
                        name: "FK_MappingModel_ModelB_ModelBId1",
                        column: x => x.ModelBId1,
                        principalTable: "ModelB",
                        principalColumn: "Id",
                        onDelete: ReferentialAction.Restrict);
                });

还有 2 个额外的外键:ModelAId1 和 ModelBId1。此行为是意外的。以及如何使用 fluent API 显式映射映射表关系?

如果您评论使用 fluent API 制作的显式关系(最后 2 部分),您会得到预期的结果。

标签: c#entity-frameworkentity-framework-coreentity-framework-migrations

解决方案


推荐阅读