Entity Framework, сопоставляющий внешний ключ с коллекциями и TPH-инхерикантом

Я пытаюсь отобразить эту простую модель с наследованием TPH:

    public abstract class Master {
    public long Id {
        get;
        set;
    }
    public virtual ICollection<Detail> Details {
        get;
        set;
    }

}

public class MasterA : Master {
    public string FieldA {
        get;
        set;
    }
}

public class MasterB : Master {
    public string FieldB {
        get;
        set;
    }
}

public abstract class Detail {
    public long Id {
        get;
        set;
    }
    public long MasterId {
        get;
        set;
    }
    public Master Master {
        get;
        set;
    }
    public String CommonDetailInfo {
        get;
        set;
    }
}

public class DetailA : Detail {
    public MasterA MasterA {
        get;
        set;
    }

    public string SpecificA {
        get;
        set;
    }
}

public class DetailB : Detail {
    public MasterB MasterB {
        get;
        set;
    }
    public string SpecificB {
        get;
        set;
    }
}

Сопоставление выполняется с беглой нотацией

modelBuilder.Entity<Master>().ToTable("TestMaster");
        modelBuilder.Entity<Master>().Property(m => m.Id)
                                     .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
        modelBuilder.Entity<Master>().HasKey(m => m.Id);
        modelBuilder.Entity<Master>().Map<MasterA>(m => m.Requires("MasterType").HasValue("A"));
        modelBuilder.Entity<Master>().Map<MasterB>(m => m.Requires("MasterType").HasValue("B"));

        modelBuilder.Entity<Detail>().ToTable("TestDetail");
        modelBuilder.Entity<Detail>().Property(d => d.Id)
                                     .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
        modelBuilder.Entity<Detail>().HasKey(d => d.Id);
        modelBuilder.Entity<Detail>().Map<DetailA>(m => m.Requires("DetailType").HasValue("A"));
        modelBuilder.Entity<Detail>().Map<DetailB>(m => m.Requires("DetailType").HasValue("B"));

        modelBuilder.Entity<Master>()
            .HasMany(m => m.Details)
            .WithRequired(d => d.Master)
            .HasForeignKey(f => f.MasterId)
            .WillCascadeOnDelete();

Если я позволю EF создать свою базу данных, в таблицу TestDetail будут добавлены два поля:

MasterA_Id
MasterB_Id

Но эти два поля всегда равны Null и являются избыточными, потому что поле MasterId в базовом классе Dteail выполняет одну и ту же работу?

Если я удалю эти поля из базы данных и попытаюсь получить подробности об основной записи следующим образом:

  foreach (var detail in master.Details) {...}

Возникает исключение: неверное имя столбца MasterA_Id, MasterB_Id при доступе к свойству "Подробности".

Что я делаю не так? Как я могу сопоставить эту модель в режиме TPH, не имея этих двух полей в базе данных?

Спасибо за вашу помощь.

0 ответов

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