【问题标题】:Unexpected foreign key generated for one to many relationship为一对多关系生成了意外的外键
【发布时间】:2026-02-09 05:35:01
【问题描述】:

我已经声明了两个类——Person 和 Vehicle,如下所示

public class Person
{
    public Person()
    {
        this.Vehicles = new HashSet<Vehicle>();
    }

    [Key]
    public int PersonID { get; set; }

    [Required, MaxLength(50)]
    public string FirstName { get; set; }

    [Required, MaxLength(50)]
    public string MiddleName { get; set; }

    [Required, MaxLength(50)]
    public string LastName { get; set; }

    [Required, MaxLength(10)]
    public string MobileNo1 { get; set; }
    [MaxLength(10)]
    public string MobileNo2 { get; set; }

    [MaxLength(50)]
    public string Email1 { get; set; }
    [MaxLength(50)]
    public string Email2 { get; set; }

    public virtual ICollection<Vehicle> Vehicles { get; set; }
}

public class Vehicle
{
    [Key]
    public int VehicleID { get; set; }

    [MaxLength(20)]
    public string VehicleNumber { get; set; }

    [ForeignKey("VehicleOwner")]
    public int? VehicleOwnerID { get; set; }
    [ForeignKey("VehicleOwnerID")]
    public virtual Person VehicleOwner { get; set; }

    [ForeignKey("VehicleDriver")]
    public int? VehicleDriverID { get; set; }
    [ForeignKey("VehicleDriverID")]
    public virtual Person VehicleDriver { get; set; }

    [ForeignKey("Person")]
    public int? PersonID { get; set; }
    [ForeignKey("PersonID")]
    public virtual Person Person { get; set; }

}

这会在 Vehicles 表上生成两个外键

.ForeignKey("dbo.Person", t => t.PersonID)
.ForeignKey("dbo.Person", t => t.Person_PersonID)

而我所期望的只是

.ForeignKey("dbo.Person", t => t.PersonID)

最初我认为这可能是因为我错过了将实体声明为虚拟的,但事实并非如此。我无法检测到此代码的问题。

像 Vehicles 一样,我还有另一个类 - Documents,其结构和关系与 Person 有点相同。但是对于 Documents,外键是按预期生成的。

【问题讨论】:

    标签: c# .net entity-framework entity-framework-migrations ef-fluent-api


    【解决方案1】:

    你有3个类指向Person,所以配置为:

    public class Vehicle
    {
        [Key]
        public int VehicleID { get; set; }
    
        [MaxLength(20)]
        public string VehicleNumber { get; set; }
    
        public int? VehicleOwnerID { get; set; }
        [ForeignKey("VehicleOwnerID")]
        public virtual Person VehicleOwner { get; set; }
    
        public int? VehicleDriverID { get; set; }
        [ForeignKey("VehicleDriverID")]
        public virtual Person VehicleDriver { get; set; }
    
        public int? PersonID { get; set; }
        [ForeignKey("PersonID")]
        public virtual Person Person { get; set; }
    
    }
    

    虽然语法不正确,但第二个外键来自人的车辆集合,而 EF 无法解析它属于哪个 FK。

    因此,在您的集合中的 Person 类中,您需要指向车辆中相应的导航:

    [InverseProperty("Person")]
    public virtual ICollection<Vehicle> Vehicles { get; set; }
    

    http://www.entityframeworktutorial.net/code-first/inverseproperty-dataannotations-attribute-in-code-first.aspx

    【讨论】:

    • 我认为这可能会做到。让我试试然后回来
    【解决方案2】:

    正如史蒂夫所说,这是因为您从车辆类中引用了 Person。因此,Entity Framework 为 Person、VehicleOwner 和 VehicleDriver 创建了 3 个键。然而,由于从人那里收集车辆,它创建了另一个密钥。您必须在此处使用 inverse 属性来告诉 Entity Framework 您的意思是在实际的 Vehicle.Person 属性上建立 Vehicle 和 Person 之间的关系。你可以这样做

    [InverseProperty("Person")]
    public virtual ICollection<Vehicle> Vehicles { get; set; }
    

    另外,你是多余的:

    [ForeignKey("Person")]
    public int? PersonID { get; set; }
    [ForeignKey("PersonID")]
    public virtual Person Person { get; set; }
    

    从 int 中删除 ForeignKey?车辆类中的 PersonID。

    【讨论】:

    • 冗余,但集合是导致添加 Person_PersonID 的原因。
    • @Jared 我尝试了你的解决方案,但仍然遇到同样的问题
    • @MufaddalGulshan 我现在看到了更多您的问题。这是因为史蒂夫在说什么。