【问题标题】:ef core code first generic inheritance mappingef核心代码优先泛型继承映射
【发布时间】:2019-03-03 18:45:14
【问题描述】:

所有位置都有一个位置(多对一)。 不同的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; }

任何见解将不胜感激。

【问题讨论】:

    标签: c# .net-core domain-driven-design entity-framework-core-2.1 ef-code-first-mapping


    【解决方案1】:

    我不确定 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>();
        }
    

    【讨论】:

    • 稍作调整就解决了我的用例。谢谢!
    猜你喜欢
    • 1970-01-01
    • 2011-08-12
    • 1970-01-01
    • 1970-01-01
    • 2014-08-31
    • 1970-01-01
    • 1970-01-01
    • 2012-09-27
    • 1970-01-01
    相关资源
    最近更新 更多