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 约束。
我无法为 Car
和 Person
创建基础 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);
但是如您所见,使用此模型,您将在 Person
和 GeoInfo
以及 Car
和 GeoInfo
之间建立一对多关系。我认为这个模型可以更真实,因为,例如,两个人可以有相同的坐标。
我使用的是 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 约束。
我无法为 Car
和 Person
创建基础 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);
但是如您所见,使用此模型,您将在 Person
和 GeoInfo
以及 Car
和 GeoInfo
之间建立一对多关系。我认为这个模型可以更真实,因为,例如,两个人可以有相同的坐标。