Entity Framework6:与继承的一对一关系

Entity Framework 6: one-to-one relationship with inheritance

我使用的是 EF6 Code First,这是一个重现我的问题的简单模型:

abstract class GeoInfo
{
    public int Id { get; set; }
    public double CoordX { get; set; }
    public double CoordY { get; set; }
}

class PersonGeoInfo : GeoInfo
{
    [Required]
    public Person Person { get; set; }
}

class CarGeoInfo : GeoInfo
{
    [Required]
    public Car Car { get; set; }
}

class Person
{
    public int Id { get; set; }
    public string Name { get; set; }
    public virtual PersonGeoInfo PersonGeoInfo { get; set; }
}

class Car
{
    public int Id { get; set; }
    public string Number { get; set; }
    public virtual CarGeoInfo CarGeoInfo { get; set; }
}

还有上下文:

class MyContext : DbContext
{
    public DbSet<GeoInfo> GeoInfos { get; set; }
    public DbSet<PersonGeoInfo> PersonGeoInfos { get; set; }
    public DbSet<CarGeoInfo> CarGeoInfos { get; set; }
    public DbSet<Person> Persons { get; set; }
    public DbSet<Car> Cars { get; set; }
}

Entity Framework 生成此数据库:

查看GeoInfoes 外键约束。它们都在一列中,使用这个数据库是不可能的。但是 EF 没有警告我,它只是抛出数据库异常:The INSERT statement conflicted with the FOREIGN KEY...

我试过使用 TPT 策略 - 同样的问题,但关联键和继承键之间存在混合。

我试图在模型中明确定义外键 - 没有帮助。没有什么能阻止 EF 在同一 PK 列中生成 FK 约束。

我无法为 CarPerson 创建基础 class,因为在实际应用中它们已经参与了另一个层次结构。

我是在使用 Entity Framework 错误还是它真的无法将一对一关系连同继承映射到数据库?

我想你可以用这个模型解决你的问题:

public class GeoInfo
{
    public int Id { get; set; }
    public double CoordX { get; set; }
    public double CoordY { get; set; }

}

public class Person
{
    public int Id { get; set; }
    public string Name { get; set; }

    [ForeignKey("PersonGeoInfo")]
    public int? PersonGeoInfoId { get; set; }

    public virtual GeoInfo PersonGeoInfo { get; set; }
}

public class Car
{
    public int Id { get; set; }
    public string Number { get; set; }

    [ForeignKey("CarGeoInfo")]
    public int? CarGeoInfoId { get; set; }

    public virtual GeoInfo CarGeoInfo { get; set; }
}

这样,一个 Person 和一个 Car 与一个 GeoInfo 相关联,当你想通过他们的坐标找到一个人时,你可以这样做:

 int geoInfoId = 3;
 var person=_db.Persons.FirstOrDefault(p=>p.PersonGeoInfoId==geoInfoId);

但是如您所见,使用此模型,您将在 PersonGeoInfo 以及 CarGeoInfo 之间建立一对多关系。我认为这个模型可以更真实,因为,例如,两个人可以有相同的坐标。