我正在使用.NET Core 3.1与EF Core。
我有一个简单的客户端-事件关系示例:
public class BaseEntity
{
[Key]
[Required]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public DateTime CreatedOn { get; set; }
public DateTime? ModifiedOn { get; set; }
}
public class Client : BaseEntity
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Email { get; set; }
public string Phone { get; set; }
}
public class Event : BaseEntity
{
public DateTime Start { get; set; }
public DateTime End { get; set; }
public Client Client { get; set; }
}
在我的场景中,我正在使用Fluent API来指定关联关系:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Event>()
.HasOne<Client>()
.WithMany()
.IsRequired()
.OnDelete(DeleteBehavior.Cascade);
}
当我创建迁移时,客户端表看起来没问题,但事件表看起来是这样的:
migrationBuilder.CreateTable(
name: "Events",
columns: table => new
{
Id = table.Column<int>(nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
CreatedOn = table.Column<DateTime>(nullable: false),
ModifiedOn = table.Column<DateTime>(nullable: true),
Start = table.Column<DateTime>(nullable: false),
End = table.Column<DateTime>(nullable: false),
ClientId = table.Column<int>(nullable: false),
ClientId1 = table.Column<int>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Events", x => x.Id);
table.ForeignKey(
name: "FK_Events_Clients_ClientId",
column: x => x.ClientId,
principalTable: "Clients",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_Events_Clients_ClientId1",
column: x => x.ClientId1,
principalTable: "Clients",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
最终我得到了两列:ClientId和ClientId1。为什么Entity Framework会为我的关系创建两列?
迄今为止,我还没有使用Fluent API,只是使用自动生成的影子属性ClientId就可以完美地工作了,但我需要为这些实体配置级联删除,而且由于没有其他方法可以实现它,所以我按照上面的示例指定了关系。从那时起,就有了额外的外键列。
我尝试指定一个外键列:
modelBuilder.Entity<Event>()
.HasOne<Client>()
.WithMany()
.IsRequired()
.HasForeignKey("ClientId")
.OnDelete(DeleteBehavior.Cascade);
目前没有任何效果。有没有办法告诉 EF 我正在使用自动生成的 Shadow 属性?
编辑 #1:
我也尝试了自己指定外键属性,像这样:
public class Event : BaseEntity
{
public DateTime Start { get; set; }
public DateTime End { get; set; }
public int ClientId { get; set; }
public Client Client { get; set; }
}
然后
modelBuilder.Entity<Event>()
.HasOne<Client>()
.WithMany()
.IsRequired()
.HasForeignKey(e => e.ClientId)
.OnDelete(DeleteBehavior.Cascade);
但是仍然没有任何效果。