ef базовый код первого общего отображения наследования - PullRequest
0 голосов
/ 03 марта 2019

Все позиции имеют местоположение (Many-to-1).Разные типы Location имеют разные типы Position

Модель:

public abstract class Location
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int AreaId { get; set; }
    public Area Area { get; set; }
    public byte[] ConcurrencyToken { get; set; }
}
public abstract class Location<T> : Location where T : Position
{
    public ICollection<T> Positions { get; set; } = new List<T>();
}

public class Bay : Location<BayRow> {}
public class StandardLocation : Location<Position> {}

public class Position
{
    public int Id { get; set; }
    public int? Place { get; set; }
    public int LocationId { get; set; }
    public Location Location { get; set; }
    public byte[] ConcurrencyToken { get; set; }
}
public class BayRow : Position
{
    public int? Row { get; set; }
}

Выше приведено сокращение, есть много других реализаций каждого.Все местоположения расширяют универсальный класс.

Отображение:

modelBuilder.Entity<Position>(entity =>
{                
    entity.ToTable("Position")
          .HasDiscriminator<int>("Type")
          .HasValue<Position>(1)
          .HasValue<BayRow>(2);
    entity.Property(x => x.ConcurrencyToken).IsConcurrencyToken();
    //THIS IS THE ISSUE*
    entity.HasOne(x => x.Location as Location<Position>).WithMany(x => x.Positions).HasForeignKey(x => x.LocationId);
});

modelBuilder.Entity<Location>(entity =>
{
    entity.HasIndex(x => new {x.Name, x.AreaId}).IsUnique(true);
    entity.Property(x => x.ConcurrencyToken).IsConcurrencyToken();
    entity.HasDiscriminator<int>("Type")
          .HasValue<StandardLocation>(1)
          .HasValue<Bay<BayRow>>(2)
});

modelBuilder.Entity<Bay<BayRow>>(entity =>
{
    entity.HasMany(x => x.Positions).WithOne(x => x.Location as Bay<BayRow>)
                .HasForeignKey(x => x.LocationId).OnDelete(DeleteBehavior.Cascade);
});

modelBuilder.Entity<BayRow>(entity =>
{
    entity.Property(x => x.Row).HasColumnName("Row");
});

* Неуниверсальное местоположение не имеет позиций

Я пытался добавить коллекцию в базуМестоположение исключительно для отображения, чтобы избежать дублирования / наложения каждого местоположения Impl, т.е. BayId как LocationId.

publiic ICollection<Position> Positions { get; set; }

и с ключевым словом new , чтобы скрыть базовую коллекцию, но ef проектирует 2 коллекции ...

public new ICollection<T> Positions { get; set; }

Любое понимание будет высоко ценится.

1 Ответ

0 голосов
/ 04 марта 2019

Я не уверен, что это поддерживается Entity Framework без генерации двух таблиц - одной для Bay и одной для StandardLocation.

Вы можете попробовать это в качестве обходного пути.

    public interface ITypedPosition<T> where T: Position
    {
        IEnumerable<T> Positions { get; }
    }

    public abstract class Location
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public int AreaId { get; set; }
        public Area Area { get; set; }
        public byte[] ConcurrencyToken { get; set; }
        public ICollection<Position> Positions { get; set; }
    }

    public class Bay : Location, ITypedPosition<BayRow>
    {
        IEnumerable<BayRow> ITypedPosition<BayRow>.Positions => base.Positions.OfType<BayRow>();
    }
    public class StandardLocation : Location, ITypedPosition<Position>
    {
        IEnumerable<Position> ITypedPosition<Position>.Positions => base.Positions.OfType<Position>();
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...