EF Core 创建多个外键列 [英] EF Core creates multiple foreign key columns

查看:32
本文介绍了EF Core 创建多个外键列的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm using EF Core with .NET Core 3.1

我有一个简单的客户端-事件关系示例:

I have simple example of Client-Event relationship:

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 来指定关系:

In my context, I'm using Fluent API to specify relationships:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
        
    modelBuilder.Entity<Event>()
        .HasOne<Client>()
        .WithMany()
        .IsRequired()
        .OnDelete(DeleteBehavior.Cascade);

}

当我创建迁移时,客户端表看起来不错,但事件表看起来像这样:

When I create migration, the client table looks fine, but the event table looks like this:

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.为什么实体框架会为我的关系创建两列?

Finally I end up having two columns: ClientId and ClientId1. Why is Entity Framework creating two columns for my relationship?

到目前为止,我没有使用 Fluent API,它仅与自动生成的影子属性 ClientId 完美配合,但我需要从该实体配置级联删除,并且由于没有其他方法可以做到这一点,我指定了关系如上图.从那时起,它就有了额外的外键列.

I wasn't using Fluent API so far and it worked perfectly with just shadow property ClientId auto-generated, but I needed to configure cascade delete form this entities, and since there is no other way to do it, I specified the relationship as pictured above. Since then, there is additional foreign key column for it.

我尝试指定一个外键列:

I tried specifying a foreign key column:

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

目前没有效果.有没有办法告诉 EF im 使用自动生成的阴影属性?

No effect so far. Is there any way to tell EF im using auto generated shadow properties?

编辑 #1:

我也尝试过像这样自己指定外键属性:

I also tried specyfing Foreign keys properties on my own like this:

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

但是还是没有效果.

推荐答案

事实证明,关系可以是空的 - 将决定留给框架,但这并不能真正满足您的兴趣.我修改了我的代码,所以有明确的指向导航属性,EF 识别出这种关系并停止为列创建阴影属性:

It turns out, relationships can be empty - leaving decision to the framework, but it doesn't really serve Your interest. I modified my code, so there is explicit pointing at the navigation property, and EF recognized the relationship and stopped creating shadow properties for the columns:

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

这篇关于EF Core 创建多个外键列的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆