EF Core创建多个外键列

时间:2019-12-24 07:54:24

标签: c# .net entity-framework core

我将EF Core与.Net Core 3.1一起使用

我有一个简单的Client-Event关系示例:

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; }
}

在我的上下文中,我使用 FluentAPI 指定关系:

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 。为什么EntifyFramework为我的关系创建两列?

到目前为止,我还没有使用FluentApi,它只与阴影属性ClientId自动生成完美配合,但是我需要从该实体配置级联删除,并且由于没有其他方法,我指定了如图所示的关系以上。从那以后,它有了额外的外键列。

我尝试指定外键列:

modelBuilder.Entity<Event>()
            .HasOne<Client>()
            .WithMany()
            .IsRequired()
            .HasForeignKey("ClientId")
            .OnDelete(DeleteBehavior.Cascade);

到目前为止没有效果。有什么方法可以使用自动生成的阴影属性告诉EF im?

编辑#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 个答案:

答案 0 :(得分:1)

事实证明,关系可以是空的-由框架来决定,但这并不能真正满足您的兴趣。我修改了代码,因此显式指向了导航属性,EF识别了这种关系并停止为列创建阴影属性:

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

答案 1 :(得分:1)

您可以尝试以下方法:

{

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

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