【发布时间】:2022-01-27 13:59:49
【问题描述】:
我正在使用 Visual Studio Community 2022(64 位,版本 17.1.0 预览版 1.1)、ASP .Net 5 Razor Pages(非 MVC)、EF Core 5 和 SQL Server。
我有两个类,它们具有多对多关系。
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; }
}
第 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 类以方便在数据库中创建 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 表,原因我无法理解。
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");
}
感谢任何帮助。谢谢。
【问题讨论】:
-
我首先要看的是你似乎在你的实体之间建立了两次关系。一个标签有一个
ICollection<Acronym>属性(首字母缩略词有一个ICollection<Tag>),EF 会理解它是一个直接的多:多,它会让中间人表让你将它分成两个多:1 rels.. 但是你然后也让每个 ent 都有一个List<TagAcronym>以便让 EF 通过制作自己的中间人来帮助您,您还可以手动制作自己的中间人实体。决定你想要的工作方式(隐藏的或可见的中间人)并移除另一个,看看会发生什么...... -
(我个人会删除
ICollection<Tag/Acronym>道具,将List<TagAcronym>翻转为ICollection并将其初始化为哈希集而不是列表,并与可见的中间人一起工作:someTag.TagAcronym.Acronyms.Where(...)vssomeTag.Acronyms.Where(...)因为我发现迟早,可能更早,老板想要一些东西,这意味着我需要在 TagAcronym 表中存储更多数据..) -
您能否包括在您的上下文中如何配置实体?您的实体设置与官方docs 接近,但有些偏差。
-
是的,@CaiusJard 你的解释非常详细和正确。
-
如何配置多对多连接?还是一切都是按照惯例推断出来的?恕我直言,改为明确定义关系 (docs.microsoft.com/en-us/ef/core/modeling/…)。
标签: c# asp.net-core entity-framework-core razor-pages