实体框架6:与继承有一对一的关系 [英] Entity Framework 6: one-to-one relationship with inheritance
问题描述
抽象类GeoInfo $ b $我使用的是EF6 Code First,这是一个简单的模型, b {
public int Id {get;组; }
public double CoordX {get;组; }
public double CoordY {get;组; }
}
class PersonGeoInfo:GeoInfo
{
[必需]
public Person Person {get;组;
}
class CarGeoInfo:GeoInfo
{
[必需]
public Car Car {get;组; }
}
class Person
{
public int Id {get;组; }
public string Name {get;组; }
public virtual PersonGeoInfo PersonGeoInfo {get;组; }
}
class Car
{
public int Id {get;组; }
public string Number {get;组; }
public virtual CarGeoInfo CarGeoInfo {get;组; }
}
和上下文:
class MyContext:DbContext
{
public DbSet< GeoInfo> GeoInfos {get;组; }
public DbSet< PersonGeoInfo> PersonGeoInfos {get;组; }
public DbSet< CarGeoInfo> CarGeoInfos {get;组; }
public DbSet< Person>人{get;组; }
public DbSet< Car>汽车组; }
}
实体框架生成此数据库:
查看在 GeoInfoes
外键约束。他们都在一列,使用这个数据库是不可触知的。但是EF没有警告我,它只是抛出数据库异常: INSERT语句与FOREIGN KEY冲突...
我试图使用TPT策略 - 同样的问题,但是在关联和继承密钥之间进行混合。
我试图明确定义外键模型 - 没有帮助。没有什么可以阻止EF在同一个PK列中生成FK约束。
我不能为 Car $ c创建基类$ c>和
Person
因为在真实的应用程序中,他们已经参与了另一个层次结构。
我使用实体框架错误,或者真的不能将一对一的关系与继承映射到数据库?
我想你可以使用此模型解决您的问题:
public class GeoInfo
{
public int Id {get;组; }
public double CoordX {get;组; }
public double CoordY {get;组; }
}
public class Person
{
public int Id {get;组; }
public string Name {get;组; }
[ForeignKey(PersonGeoInfo)]
public int? PersonGeoInfoId {get;组; }
public virtual GeoInfo PersonGeoInfo {get;组;
}
public class Car
{
public int Id {get;组; }
public string Number {get;组; }
[ForeignKey(CarGeoInfo)]
public int? CarGeoInfoId {get;组; }
public virtual GeoInfo CarGeoInfo {get;组; }
}
这样,一个 Person
和 Car
与 GeoInfo
相关联,当您想通过坐标找到一个人时你可以这样做:
int geoInfoId = 3;
var person = _db.Persons.FirstOrDefault(p => p.PersonGeoInfoId == geoInfoId);
但是,您可以看到,使用此模型,您将在 Person
和 GeoInfo
和 Car
和地理信息
。我认为这个模型可能更真实,因为例如两个人可以有相同的坐标。
I'm using EF6 Code First and here's a simple model which reproduces my issue:
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; }
}
And a context:
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 generates this database:
Look at GeoInfoes
foreign keys constraints. They both are in one column and using this database is imposible. But EF didn't warned me, it just throws database exception: The INSERT statement conflicted with the FOREIGN KEY...
I've tried to use TPT strategy - the same problem, but mixing is between association and inheritance keys.
I've tried to explicitly define foreign keys in model - didn't help. Nothing stops EF from generating a FK constraint in the same PK column.
I can't create a base class for a Car
and a Person
because in real app they are already participate in another hierarchies.
Am I using Entity Framework wrong or it really can't map one-to-one relationship along with inheritance to a database?
I think you can resolve your problem with this model:
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; }
}
This way, a Person
and a Car
are associated with a GeoInfo
, and and when you want to find a person by their coordinates, you could do this:
int geoInfoId = 3;
var person=_db.Persons.FirstOrDefault(p=>p.PersonGeoInfoId==geoInfoId);
But as you can see, with this model you are going to have one-to many relationships between Person
and GeoInfo
and Car
and GeoInfo
. I think this model could be more real because, eg, two people could have the same coordinates.
这篇关于实体框架6:与继承有一对一的关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!