EF Core创建了多个外键列

4

我正在使用.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);
            });

最终我得到了两列:ClientIdClientId1。为什么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);

但是仍然没有任何效果。

2个回答

5

事实证明,关系可以是空的 - 让框架决定,但这并不符合您的利益。我修改了我的代码,所以在导航属性上明确指向关系,EF识别了这种关系并停止为列创建影子属性:

modelBuilder.Entity<Event>()
    .HasOne<Client>(e => e.Client)
    .WithMany()
    .IsRequired()
    .OnDelete(DeleteBehavior.Cascade);

1
您可以尝试这个:
{

    public DateTime Start { get; set; }
    public DateTime End { get; set; }
    public int? ClientId { get; set; }

    [ForeignKey("ClientId ")]
    public virtual Client Client { get; set; }
}

1
其实我已经尝试过这个方法,但不幸的是它行不通。它只会告诉EF在Event实体中查找ClientId属性,但由于没有明确声明属性,我指望框架自己创建它 - 无论是让框架创建还是自己创建都没有影响。FluentAPI不会将其识别为关系,并强制创建新属性。 - Karol Pawlak
尝试这个,不要使用<Client>。```c# .HasOne(e => e.Client) - Gjurgica

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接