Таблица Entity Framework для каждой иерархии, вставка нескольких столбцов идентификаторов

Я серьезно потратил два рабочих дня, пытаясь настроить TPH сначала с базы данных на код. Я получаю что-то вроде «Недопустимое имя столбца Entity_EntityId / Entity_Entity_Id1».

Я составил очень простую репродукцию проблемы:

      internal class Program
      {
        private static void Main(string[] args)
        {
          using (var context = new Context())
          {
            var baseClass = new Base {Name = "Test"};
            context.BaseClasses.Add(baseClass);
            context.SaveChanges();
            var baseClasses = context.BaseClasses.ToList();
          }
        }
      }

Контекст:

      public class Context : DbContext
      {
        public Context() : base("TPH")
        {
        }

        public DbSet<Base> BaseClasses { get; set; }
        public DbSet<Derived> DervDerivedClasses { get; set; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
        }
      }

Сопоставление:

      public class BaseMap : EntityTypeConfiguration<Base>
      {
        public BaseMap()
        {
          HasKey(b => b.Id);

          Property(b => b.Name);
          HasOptional(b => b.AnotherClass)
            .WithMany(b => b.Bases)
            .HasForeignKey(b => b.AnotherClassId);

          Map(b => b.Requires("Disc").HasValue(1));
        }
      }

      public class DerivedMap : EntityTypeConfiguration<Derived>
      {
        public DerivedMap()
        {
          HasKey(b => b.Id);

          Property(b => b.Name);
          HasOptional(b => b.AnotherClass)
            .WithMany(b => b.Deriveds)
            .HasForeignKey(b => b.AnotherClassId);

          Map(b => b.Requires("Disc").HasValue(2));
        }
      }

      public class SecondDerivedMap : EntityTypeConfiguration<SecondDerived>
      {
        public SecondDerivedMap()
        {
          HasKey(b => b.Id);

          Property(b => b.Name);

          HasOptional(b => b.AnotherClass)
            .WithMany(b => b.SecondDeriveds)
            .HasForeignKey(b => b.AnotherClassId);

          Map(b => b.Requires("Disc").HasValue(3));
        }
      }

Сущности:

      public class Base
      {
        public int Id { get; set; }
        public string Name { get; set; }
        public int? AnotherClassId { get; set; }
        public AnotherClass AnotherClass { get; set; }
      }

      public class Derived : Base
      {
      }

      public class SecondDerived : Base
      {
      }

      public class AnotherClass
      {
        public int Id { get; set; }
        public ICollection<Base> Bases { get; set; }
        public ICollection<Derived> Deriveds { get; set; }
        public ICollection<SecondDerived> SecondDeriveds { get; set; }
      }

Как я могу получить в таблице только один "AnotherClassId"?




Ответы (1)


У вас должно быть только одно свойство навигации для каждой сущности на отношение - а у вас их три (Bases, Deriveds и SecondDeriveds). EF видит эти свойства и полагает, что между AnotherClass и различными классами в Base иерархии существуют три разные связи типа «один ко многим».

Если вы хотите получить коллекцию связанных Derived сущностей из AnotherClass, вы должны использовать что-то вроде anotherClassEntity.Bases.OfType<Derived>().

person jjj    schedule 15.08.2015
comment
Нет вранья, я только что проснулся и пришел к такому точному выводу в духе «Ну ладно, ни хрена», спасибо за подтверждение и за вашу проницательность. - person Chazt3n; 17.08.2015