实体框架6:与继承有一对一的关系 [英] Entity Framework 6: one-to-one relationship with inheritance

查看:197
本文介绍了实体框架6:与继承有一对一的关系的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

 抽象类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 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆