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);
}
Tag 和 Acronym 之间的关系是多对多的,因此 EF 会自动为这些 table 名称(TagAcronym 或 AcronymTag)创建一个映射器 table,因此您不需要显式指定 TagAcroymn table.
我正在使用 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);
}
Tag 和 Acronym 之间的关系是多对多的,因此 EF 会自动为这些 table 名称(TagAcronym 或 AcronymTag)创建一个映射器 table,因此您不需要显式指定 TagAcroymn table.