Entity Framework Code First Two navigationProperty в / из одного абстрактного объекта

Следующие сущности - это мой первый код, PersonParameter - абстрактный класс, и Shirt и Shoes наследуются от него с помощью typ(1,2).

[Table("Person")]
public class Person
{
    [Key]
    public int id { get; set; }
    public string Name { get; set; }

    public int? shirtID { get; set; }
    public int? shoesID { get; set; }

    [ForeignKey("shirtID")]
    public Shirt Shirt { get; set; }
    [ForeignKey("shoesID")]
    public Shoes Shoes { get; set; }
}

[Table("PersonParameter")]
public abstract class PersonParameter
{
    public int id { get; set; }
    public string Title { get; set; }
    public string Value { get; set; }

    public List<Person> Persons { get; set; }
}

public class Shirt : PersonParameter
{

}
public class Shoes : PersonParameter
{

}

и для модели dbcontext

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<PersonParameter>()
        .Map<Shirt>(p => p.Requires("typ").HasValue(1))
        .Map<Shoes>(p => p.Requires("typ").HasValue(2));
}

но приведенные выше коды создадут нежелательное поле PersonParameter_id в таблице Person:

public override void Up()
{
    CreateTable(
        "dbo.PersonParameter",
        c => new
            {
                id = c.Int(nullable: false, identity: true),
                Title = c.String(),
                Value = c.String(),
                typ = c.Int(nullable: false),
            })
        .PrimaryKey(t => t.id);

    CreateTable(
        "dbo.Person",
        c => new
            {
                id = c.Int(nullable: false, identity: true),
                Name = c.String(),
                shirtID = c.Int(),
                shoesID = c.Int(),
                PersonParameter_id = c.Int(),
            })
        .PrimaryKey(t => t.id)
        .ForeignKey("dbo.PersonParameter", t => t.shirtID)
        .ForeignKey("dbo.PersonParameter", t => t.shoesID)
        .ForeignKey("dbo.PersonParameter", t => t.PersonParameter_id)
        .Index(t => t.shirtID)
        .Index(t => t.shoesID)
        .Index(t => t.PersonParameter_id);

}

Как я могу решить эту проблему (PersonParameter_id) Я сделал некоторые FluentApi с HasOptional.WithMany, но не решил.

РЕДАКТИРОВАТЬ
После некоторого теста выяснилось, что для неабстрактного класса также создается дополнительный идентификатор, и единственным решением для устранения этой проблемы является удаление свойства навигации из класса параметров и добавление его в классы наследования (рубашка и обувь)

1 ответ

Причина, по которой вы получаете одну дополнительную FK для таблицы Persons, заключается в свойстве Persons класса PersonParameter. По сути, EF не может связать это ни с одним из двух текущих отношений, определенных (Shirt и Shoes) и полагать, что свойство Persons должно быть третьим отношением между таблицами Persons и PersonParamter, и поэтому создает третий FK (PersonParameter_id) для создания этого отношения. В результате вы получаете 3 однонаправленных отношения "многие к одному" от PersonParameter к Persons.

Чтобы это исправить, вам нужно явно сказать EF, что Persons на самом деле является обратным свойством обуви и рубашек, поскольку EF не может подобрать это автоматически. Вы можете сделать это с помощью свободно распространяемого API или аннотаций, таких как:

[Table("PersonParameter")]
public abstract class PersonParameter
{
    public int id { get; set; }
    public string Title { get; set; }
    public string Value { get; set; }
}

public class Shirt : PersonParameter
{
    [InverseProperty("Shirt")]
    public List<Person> Persons { get; set; }
}

public class Shoes : PersonParameter
{
    [InverseProperty("Shoes")]
    public List<Person> Persons { get; set; }
}


Вы также можете достичь этого, используя Fluent API:

modelBuilder.Entity<Shirt>()
    .HasMany(s => s.Persons)
    .WithOptional(p => p.Shirt)
    .HasForeignKey(p => p.shirtID);

modelBuilder.Entity<Shoes>()
    .HasMany(s => s.Persons)
    .WithOptional(p => p.Shoes)
    .HasForeignKey(p => p.shoesID);
Другие вопросы по тегам