EF Core 5 迁移使用不同名称创建 Table 两次

EF Core 5 Migration Creating Table Twice With Different Name

我正在使用 Visual Studio Community 2022(64 位,版本 17.1.0 Preview 1.1),ASP .Net 5 Razor Pages(非 MVC),EF Core 5 和 SQL 服务器.

我有两个 class 是多对多的关系。

Class 1(标签):

public class Tag
{
    [Key]
    public int Id { get; set; }

    [Required]
    [Display(Name = "Tag Description")]
    [StringLength(50, ErrorMessage = "Description cannot be longer than 50 characters.")]
    public string Description { get; set; }

    [Required]
    public string Narrative { get; set; }

    //Tags Have One Subject
    //Tag.SubjectId FK
    [ForeignKey("SubjectID")]
    public int SubjectId { get; set; }
    public Subject Subject { get; set; }

    //Tags Have One Or More Documents
    //(TagDocument Join Table)
    public List<TagDocument> TagDocuments { get; set; }

    //Tags Have One Or More Acronyms
    //TagAcronym Join Table
    public ICollection<Acronym> Acronyms { get; set; }
    public List<TagAcronym> TagAcronyms { get; set; }
}

Class 2(缩写):

 public class Acronym
 {
     [Key]
     public int Id { get; set; }

     [Required]
     [Display(Name = "Acronym")]
     [StringLength(50, ErrorMessage = "Acronym cannot be longer than 50 characters.")]
     public string Abbreviation { get; set; }

     [Required]
     [Display(Name = "Description")]
     [StringLength(100, ErrorMessage = "Description cannot be longer than 100 characters.")]
     public string Description { get; set; }

     [StringLength(250, ErrorMessage = "URL cannot be longer than 250 characters.")]
     public string URL { get; set; }

     //Acronyms Have One Or More AcronymOld
     //AcronymOld.AcronymId (FK)
     public List<AcronymOld> AcronymsOld { get; set; }

     //Acronyms Have One Or More Tags
     //TagAcronym Join Table
     public ICollection<Tag> Tags { get; set; }
     public List<TagAcronym> TagAcronyms { get; set; }
 }

任何首字母缩略词可以有多个标签,一个标签可以有多个首字母缩略词。

我创建了一个 TagAcronym class 以方便在数据库中创建一个 Join Table:

 public class TagAcronym
    {
        public int TagId { get; set; }
        public Tag Tag { get; set; }

        public int AcronymId { get; set; }
        public Acronym Acronym { get; set; }
    }
}

当我创建迁移时,它试图创建一个 TagAcronym 和一个 AcronymTag table,原因我无法理解。

protected override void Up(MigrationBuilder migrationBuilder)
{
    migrationBuilder.CreateTable(
        name: "AcronymTag",
        columns: table => new
        {
            AcronymsId = table.Column<int>(type: "int", nullable: false),
            TagsId = table.Column<int>(type: "int", nullable: false)
        },
        constraints: table =>
        {
            table.PrimaryKey("PK_AcronymTag", x => new { x.AcronymsId, x.TagsId });
            table.ForeignKey(
                name: "FK_AcronymTag_Acronym_AcronymsId",
                column: x => x.AcronymsId,
                principalTable: "Acronym",
                principalColumn: "Id",
                onDelete: ReferentialAction.Cascade);
            table.ForeignKey(
                name: "FK_AcronymTag_Tag_TagsId",
                column: x => x.TagsId,
                principalTable: "Tag",
                principalColumn: "Id",
                onDelete: ReferentialAction.Cascade);
        });

    migrationBuilder.CreateTable(
        name: "TagAcronym",
        columns: table => new
        {
            TagId = table.Column<int>(type: "int", nullable: false),
            AcronymId = table.Column<int>(type: "int", nullable: false)
        },
        constraints: table =>
        {
            table.PrimaryKey("PK_TagAcronym", x => new { x.TagId, x.AcronymId });
            table.ForeignKey(
                name: "FK_TagAcronym_Acronym_AcronymId",
                column: x => x.AcronymId,
                principalTable: "Acronym",
                principalColumn: "Id",
                onDelete: ReferentialAction.Cascade);
            table.ForeignKey(
                name: "FK_TagAcronym_Tag_TagId",
                column: x => x.TagId,
                principalTable: "Tag",
                principalColumn: "Id",
                onDelete: ReferentialAction.Cascade);
        });

    migrationBuilder.CreateIndex(
        name: "IX_AcronymTag_TagsId",
        table: "AcronymTag",
        column: "TagsId");

    migrationBuilder.CreateIndex(
        name: "IX_TagAcronym_AcronymId",
        table: "TagAcronym",
        column: "AcronymId");
}

感谢任何帮助。谢谢。

你可以使用这个模型设计:

public class Tag
    {
        [Key]
        public int Id { get; set; }

        [Required]
        [Display(Name = "Tag Description")]
        [StringLength(50, ErrorMessage = "Description cannot be longer than 50 characters.")]
        public string Description { get; set; }

        [Required]
        public string Narrative { get; set; }

        //Tags Have One Subject
        //Tag.SubjectId FK
        [ForeignKey("SubjectID")]
        public int SubjectId { get; set; }
        public Subject Subject { get; set; }

        //Tags Have One Or More Documents
        //(TagDocument Join Table)
        public List<TagDocument> TagDocuments { get; set; }

        //Tags Have One Or More Acronyms
        //TagAcronym Join Table
        public List<TagAcronym> TagAcronyms { get; set; }
    }

public class Acronym
    {
        [Key]
        public int Id { get; set; }

        [Required]
        [Display(Name = "Acronym")]
        [StringLength(50, ErrorMessage = "Acronym cannot be longer than 50 characters.")]
        public string Abbreviation { get; set; }

        [Required]
        [Display(Name = "Description")]
        [StringLength(100, ErrorMessage = "Description cannot be longer than 100 characters.")]
        public string Description { get; set; }

        [StringLength(250, ErrorMessage = "URL cannot be longer than 250 characters.")]
        public string URL { get; set; }

        //Acronyms Have One Or More AcronymOld
        //AcronymOld.AcronymId (FK)
        public List<AcronymOld> AcronymsOld { get; set; }

        //Acronyms Have One Or More Tags
        //TagAcronym Join Table
        
        public List<TagAcronym> TagAcronyms { get; set; }
    }

数据上下文

protected override void OnModelCreating(ModelBuilder modelBuilder) {
            //Tag and Subject one-to-one
            modelBuilder.Entity<Subject>()
                .HasOne(b => b.Tag)
                .WithOne(i => i.Subject)
                .HasForeignKey<Tag>(b => b.SubjectId);
            //Tag and TagDocument one-to-many
            modelBuilder.Entity<Tag>()
                .HasMany(t => t.TagDocuments)
                .WithOne(g => g.Tag)
                .HasForeignKey(g => g.TagId);
            //Acronym and AcronymsOld one-to-many
            modelBuilder.Entity<Acronym>()
                .HasMany(t => t.AcronymsOld)
                .WithOne(g => g.Acronym)
                .HasForeignKey(g => g.AcronymId);

            //Acronym and Tag many-to-many
            modelBuilder.Entity<TagAcronym>()
            .HasKey(t => new { t.TagId, t.AcronymId });

            modelBuilder.Entity<TagAcronym>()
                .HasOne(pt => pt.Tag)
                .WithMany(p => p.TagAcronyms)
                .HasForeignKey(pt => pt.TagId);

            modelBuilder.Entity<TagAcronym>()
                .HasOne(pt => pt.Acronym)
                .WithMany(t => t.TagAcronyms)
                .HasForeignKey(pt => pt.AcronymId);

        }

可以参考官方文档:https://docs.microsoft.com/en-us/ef/core/modeling/relationships?tabs=fluent-api%2Cfluent-api-simple-key%2Csimple-key#many-to-many

Tag 和 Acronym 之间的关系是多对多的,因此 EF 会自动为这些 table 名称(TagAcronym 或 AcronymTag)创建一个映射器 table,因此您不需要显式指定 TagAcroymn table.