Entity Framework 6: отношения один к одному с наследованием

Я использую 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 генерировать ограничение FK в том же столбце PK.

Я не могу создать базовый класс для Car и Person потому что в реальном приложении они уже участвуют в другой иерархии.

Неправильно ли я использую Entity Framework или действительно не могу отобразить отношения один-к-одному вместе с наследованием в базу данных?

1 ответ

Решение

Я думаю, что вы можете решить вашу проблему с этой моделью:

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, Я думаю, что эта модель может быть более реальной, потому что, например, два человека могут иметь одинаковые координаты.

Другие вопросы по тегам