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