【问题标题】:Entity Framework Table per Hierarchy not creating Discriminator每个层次结构的实体框架表不创建鉴别器
【发布时间】:2015-08-27 20:27:46
【问题描述】:

经过几次迁移,我创建了一个继承层次结构。现在,当我使用代码优先迁移更新数据库时,代码优先不会自动创建鉴别器字段。此后,我删除了该表并重新创建了它(使用代码优先迁移),但没有任何运气。我唯一能想到的是派生类中没有额外的“非虚拟”属性——创建继承结构是为了强制执行一个业务规则,即只有某个派生类型可以与另一个实体有关系。

基本类型:

public abstract class Process
{

    private ICollection<ProcessSpecification> _specifications { get; set; }

    protected Process()
    {
        _specifications = new List<ProcessSpecification>();
    }        

    public Int32 Id { get; set; }
    public String Description { get; set; }
    public Int32 ToolId { get; set; }

    public virtual Tool Tool { get; set; }        
    public virtual ICollection<ProcessSpecification> Specifications
    {
        get { return _specifications; }
        set { _specifications = value; }
    }

}

派生类(没有不同/唯一的标量属性):

public class AssemblyProcess : Process
{
    private ICollection<AssemblyProcessComponent> _components;

    public AssemblyProcess()
    {
        _components = new List<AssemblyProcessComponent>();            
    }

    public virtual ICollection<AssemblyProcessComponent> Components
    {
        get { return _components; }
        set { _components = value; }
    }
}

另一个派生类型

public class MachiningProcess : Process
{
    private ICollection<MachiningProcessFeature> _features;

    public MachiningProcess()
    {
        _features = new List<MachiningProcessFeature>();
    }

    public virtual ICollection<MachiningProcessFeature> Features { get { return _features; } set { _features = value; } }
}

代码优先是否没有在数据库中添加鉴别器列,因为它看不到派生类之间的任何差异(因为没有任何独特的“非虚拟”属性)?如果是这样,我该如何解决这个问题?如果不是,代码优先不会在数据库中自动创建鉴别器列的一些​​原因是什么?我有另一个 TPH 结构,它的工作方式完全符合它的预期。

DbContext:

public LineProcessPlanningContext()
        : base("LineProcessPlanning")
    {
    }   

public DbSet<Component> Components { get; set; }
public DbSet<Customer> Customers { get; set; }
public DbSet<Feature> Features { get; set; }
public DbSet<OperationDefinition> OperationDefinitions { get; set; }
public DbSet<PartDesign> PartDesigns { get; set; }
public DbSet<Process> Processes { get; set; }
public DbSet<ProcessPlan> ProcessPlans { get; set; }
public DbSet<ProcessPlanStep> ProcessPlanSteps { get; set; }
public DbSet<ProductionLine> ProductionLines { get; set; }       
public DbSet<StationCycleDefinition> StationCycleDefinitions { get; set; }
public DbSet<StationCycleStep> StationCycleSteps { get; set; }
public DbSet<StationDefinition> StationDefinitions { get; set; }
public DbSet<UnitOfMeasurement> UnitsOfMeasurement { get; set; }        
public DbSet<Tool> Tools { get; set; }

我还尝试创建每个派生类型独有的“虚拟”属性。代码迁移将新属性作为列添加到表中,但迁移没有创建鉴别器列。

【问题讨论】:

  • 我已经完成了您上面的操作,并且我的表使用 Discriminator 列正确创建。你能告诉我你的上下文的用法以及你是如何设置你的上下文的吗?
  • 我提供了 DbContext。 “Feature”是另一个实体层次结构的抽象基类;代码迁移在数据库中为该实体创建了一个鉴别器列——无需为每个派生类创建一个数据库集。
  • 嗯,看起来您在有问题的两个表(MachiningProcessFeature 和 ProcessSpecification)中有一些代码可能会对您的问题产生影响。您能否分享所有您的代码或将其缩减为我们可以重现该问题或至少有一个更匹配的示例的版本?
  • 这件事的原因确定了吗?我也有同样的问题。
  • 我认为这与无法识别结构更改的自动代码迁移有关(它以前不是继承结构)。当我删除表格并重新开始(并添加一些流畅的配置)时,一切都按照预期的方式工作。我应该不用删除数据库就可以解决问题。

标签: c# entity-framework table-per-hierarchy


【解决方案1】:

在我的情况下,我发现了这个问题的原因,和你的一样。基类是abstract,因此 EF 不会为该类创建 TPH 表,因为它无法实例化。作为抽象基类的结果,EF 将为每个派生类创建表,因此不需要鉴别器列。

就我而言,从基类中删除abstract 是可以接受的。一旦我这样做了,EF 的 TPH 就按预期工作了。

【讨论】:

  • 我还有另一个抽象的继承结构;该结构没有遇到任何问题。
  • 我认为您在抽象类下面只有一个类,其中没有创建鉴别器的任何其他类。
  • @CoroveiAndrei 你的意思是当我们只有一个继承自抽象基类的具体类时,不会创建Discriminator 表?
  • 完全正确。只有一个具体类时,不会创建鉴别器。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多