EF一对一主体关系错误

本文关键字:错误 关系 主体 一对一 EF | 更新日期: 2023-09-27 18:11:04

我在这里看到了其他问题,在我使用EF的其他项目中,但无法找出为什么我在尝试使用EF创建带有视图的控制器时出现错误。

我得到的消息是告诉我它不理解CompanyPoolCar之间的主要关系,这是一对一的关系。

Unable to determine the principal end of association between the types PoolCar and Company.

Company 1 <-> 1 PoolCar 1 <-> * CarAllocation

我已经在从属表(PoolCar)上分配了外键,但它仍然抛出相同的错误。

我错过了什么?

[Table("Company")]
    public class Company
    {
        [Key]
        public int companyId { get; set; }
        public string companyName { get; set; }
        // navigation property
        public virtual PoolCar poolCar { get; set; }
    }
    [Table("PoolCar")]
    public class PoolCar
    {
        [Key]
        public int poolCarId { get; set; }
        public int companyId { get; set; }
        [ForeignKey("companyId")]
        public Company company { get; set; }
        public string poolCarName { get; set; }
        // navigation property
        public virtual IList<CarAllocation> carAllocations { get; set; }
    }
    [Table("CarAllocation")]
    public class CarAllocation
    {
        [Key]
        public int carAllocationId { get; set; }
        public int poolCarId { get; set; }
        [ForeignKey("poolCarId")]
        public PoolCar poolCar { get; set; }
        public string allocationName { get; set; }
    }

EF一对一主体关系错误

我想我以前可能遇到过这个问题,我认为这可能是EF中的一个bug。显然,你可以通过在fluent API中配置关系来解决这个问题,参见@vinodh答案,但如果你坚持使用数据注释,那么你可以将外键属性放在poolCarId属性上。

[Table("PoolCar")]
public class PoolCar
{
    [Key, ForeignKey("company")]
    public int poolCarId { get; set; }
    public int companyId { get; set; }
    public Company company { get; set; }
    public string poolCarName { get; set; }
    // navigation property
    public virtual IList<CarAllocation> carAllocations { get; set; }
}   

同样值得注意的是,如果您在关系的主体端没有导航属性,也就是说,如果您从Company模型中删除public virtual PoolCar poolCar { get; set; },您的代码将正常工作。

我相信这是一个bug,因为当你显式声明外键时,EF没有理由不能区分哪一边是依赖的。

解决方案1

是独立于外键和关联键的问题。所以你只要做一个流畅的映射,我们就能很清楚地理解这个问题。在您的fluent Api部分执行以下操作。

modelBuilder.Entity<Company>()
        .HasOptional(obj => obj.poolCar)
        .WithRequired(obj1 => obj1.company);