每个具体类型配置的表中的抽象类

时间:2015-07-10 07:50:04

标签: c# entity-framework entity-framework-6

我有这种简单的情况:

public abstract class Parent
{
    [Key]
    public Guid SomeId { get; set; }
}

public abstract class ParentArc
{
    public Guid ArcId { get; set; }

    public Guid StartNodeId { get; set; }
    public Guid EndNodeId { get; set; }

    public Parent StartNode { get; set; }
    public Parent EndNode { get; set; }
}

public class Node : Parent
{

}

public class Arc : ParentArc
{

}

并使用这些EntityTypeConfigurations:

public class ArcMapping : EntityTypeConfiguration<Arc>
{
    public ArcMapping()
    {
        HasKey(t => t.ArcId);
        HasRequired(p => p.StartNode).WithMany().HasForeignKey(p => p.StartNodeId).WillCascadeOnDelete(false);
        HasRequired(p => p.EndNode).WithMany().HasForeignKey(p => p.EndNodeId).WillCascadeOnDelete(false);
        Map(m =>
        {
        m.MapInheritedProperties();
        m.ToTable("Arc");
        });
    }
}

public class NodeMapping : EntityTypeConfiguration<Node>
{
    public NodeMapping()
    {
        HasKey(t => t.SomeId); 
        Map(m =>
        {
        m.MapInheritedProperties();
        m.ToTable("Node");
        });
    }
}

public class ParentArcMapping : EntityTypeConfiguration<ParentArc>
{
    public ParentArcMapping()
    {
        Map(m => m.ToTable("ParentArc"));
        HasRequired(p => p.StartNode).WithMany().HasForeignKey(p => p.StartNodeId).WillCascadeOnDelete(false);
        HasRequired(p => p.EndNode).WithMany().HasForeignKey(p => p.EndNodeId).WillCascadeOnDelete(false); 
    }
}

public class ParentMapping : EntityTypeConfiguration<Parent>
{
    public ParentMapping()
    {
        Map(m => m.ToTable("Parent"));
    }
}

在我的DBContext中,我有:

public DbSet<Node> Nodes { get; set; }
public DbSet<Arc> Arcs { get; set; }

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Conventions.Add<ForeignKeyNamingConvention>();

    modelBuilder.Configurations.Add(new ArcMapping());
    modelBuilder.Configurations.Add(new NodeMapping());
}

我已从Table per Type(TPT)切换到Table per Concrete Type(TPC),因为这样可以在批量导入时更轻松。主要的缺点是TPC没有抽象类的物理表,因此物理表中没有外键dbo.Arc:

enter image description here

有没有改变这个?

1 个答案:

答案 0 :(得分:2)

您仍需要添加ParentArc的映射配置,并定义主键及其中的关系。 Arc的映射不需要定义任何关系,因为它将通过调用MapInheritedProperties()

继承基类
public class ArcMapping : EntityTypeConfiguration<Arc>
{
    public ArcMapping()
    {
        Map(m =>
        {
            m.MapInheritedProperties();
            m.ToTable("Arc");
        });
    }
}

public class NodeMapping : EntityTypeConfiguration<Node>
{
    public NodeMapping()
    {
        HasKey(t => t.SomeId);
        Map(m =>
        {
            m.MapInheritedProperties();
            m.ToTable("Node");
        });
    }
}

public class ParentArcMapping : EntityTypeConfiguration<ParentArc>
{
    public ParentArcMapping()
    {
        HasKey(t => t.ArcId);
        HasRequired(p => p.StartNode).WithMany().HasForeignKey(p => p.StartNodeId).WillCascadeOnDelete(false);
        HasRequired(p => p.EndNode).WithMany().HasForeignKey(p => p.EndNodeId).WillCascadeOnDelete(false);
    }
}

然后在OnModelCreating

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Configurations.Add(new ParentArcMapping());

    modelBuilder.Configurations.Add(new ArcMapping());
    modelBuilder.Configurations.Add(new NodeMapping());

}