EFCore 3。
需要自己的多对多类。
我的问题是:人与人之间的关系(n->m)
我的解决方案。
创建一个实现多对多的关系类。
我为班级中的记录选择了拥有自己的 ID。
所以关系类有 1 个 PK 和 2 个 FK(都属于 Person 类)。
public class Person
{
public int ID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public List<Relationship> MyRelationships { get; set; }
public List<Relationship> TheirRelationships { get; set; }
}
//我添加为关系的人的MyRelationships。
//将我添加为关系的人的他们的关系。
public class Relationship {
public int RelationshipID { get; set; }
public DateTime Since { get; set; }
//ref to person myrelationships
public int MyID { get; set; }
public Person Me { get; set; }
//ref to person theirrelationships
public int TheirID { get; set; }
public Person They { get; set; }
}
使用 add-migration 和 update-database 我了解到,在这种特殊情况下,EFCore 无法解析哪个 FK 用于哪个关系。
我使用 fluent API 解决了这个问题。
public class ApplicationDbContext : IdentityDbContext
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
//Write Fluent API configurations here
modelBuilder.Entity<Person>()
.HasMany<Relationship>(mr => mr.MyRelationships)
.WithOne(p => p.Me)
.HasForeignKey(m => m.MyID)
.OnDelete(DeleteBehavior.NoAction);
modelBuilder.Entity<Person>()
.HasMany<Relationship>(tr => tr.TheirRelationships)
.WithOne(p => p.They)
.HasForeignKey(t => t.TheirID)
.OnDelete(DeleteBehavior.NoAction);
}
public DbSet<Person> People { get; set; }
public DbSet<Relationship> Relationships { get; set; }
}
现在 add-migration xxx 可以工作了:
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "People",
columns: table => new
{
ID = table.Column<int>(nullable: false)
.Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
FirstName = table.Column<string>(nullable: true),
MiddleName = table.Column<string>(nullable: true),
LastName = table.Column<string>(nullable: true),
Email = table.Column<string>(nullable: true),
UserID = table.Column<string>(nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_People", x => x.ID);
table.ForeignKey(
name: "FK_People_AspNetUsers_UserID",
column: x => x.UserID,
principalTable: "AspNetUsers",
principalColumn: "Id",
onDelete: ReferentialAction.Restrict);
});
migrationBuilder.CreateIndex(
name: "IX_People_UserID",
table: "People",
column: "UserID");
migrationBuilder.CreateTable(
name: "Relationships",
columns: table => new
{
RelationshipID = table.Column<int>(nullable: false)
.Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
Since = table.Column<DateTime>(nullable: false),
Kind = table.Column<int>(nullable: false),
MyID = table.Column<int>(nullable: false),
TheirID = table.Column<int>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Relationships", x => x.RelationshipID);
table.ForeignKey(
name: "FK_Relationships_People_MyID",
column: x => x.MyID,
principalTable: "People",
principalColumn: "ID");
table.ForeignKey(
name: "FK_Relationships_People_TheirID",
column: x => x.TheirID,
principalTable: "People",
principalColumn: "ID");
});
migrationBuilder.CreateIndex(
name: "IX_Relationships_MyID",
table: "Relationships",
column: "MyID");
migrationBuilder.CreateIndex(
name: "IX_Relationships_TheirID",
table: "Relationships",
column: "TheirID");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "Relationships");
migrationBuilder.DropTable(
name: "People");
}
}