【问题标题】:Table Per Hierarchy & Inherited Relationships每个层次结构和继承关系的表
【发布时间】:2025-12-30 21:45:12
【问题描述】:

我正在使用面向 .Net 4.5 的 Entity Framework 5。在我的一生中,我无法弄清楚我做错了什么,在尝试使用 Table Per Hierarchy 和 Navigation 列时导致以下错误:

列名“Game_Category”无效。
列名“Game_Value”无效。
列名“Type_Category”无效。
列名“Type_Value”无效。

这是抽象基类(注意类别和值的复合 PK):

[Table("Dictionary")]
public abstract class Lookup
{
  [Key, Column(Order = 0)]
  [StringLength(50)]
  public string Category { get; set; }

  [StringLength(100)]
  public string ExtendedValue { get; set; }

  [Required]
  public bool IsActive { get; set; }

  [Required]
  [StringLength(50)]
  public string Key { get; set; }

  [Key, Column(Order = 1)]
  public int Value { get; set; }
}

后面是两个不添加额外列的子类...

public class Game : Lookup {}

public class SetType : Lookup {}

这是具有 Game 和 SetType 的 Navigation 属性的类...

public class CardSet
{
  [Required]
  [StringLength(10)]
  public string Abbreviation { get; set; }

  public virtual Game Game { get; set; }

  [Required]
  public int GameId { get; set; }

  [Key]
  public int Id { get; set; }

  [Required]
  [StringLength(100)]
  public string Name { get; set; }

  [Required]
  public DateTime ReleaseDate { get; set; }

  public virtual Lookup Type { get; set; }

  [Required]
  public int TypeId { get; set; }
}

从我的数据上下文...

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
  modelBuilder.Entity<Lookup>()
    .Map<Game>(l => l.Requires("LookupType").HasValue("Game"))
    .Map<SetType>(l => l.Requires("LookupType").HasValue("Set Type"));

  base.OnModelCreating(modelBuilder);
}

查找表有一个名为 LookupType 的鉴别器列。我已经阅读了几个关于表/继承的教程。其他两个 - TPT 和 TPC 使用类似构建的对象是小菜一碟。虽然我理解上面的错误 - 它按照惯例正在寻找 FK 列,但我不明白我做错了什么或遗漏了什么导致它查找这些列。我尝试将 ForeignKey 属性放在 GameId 和 TypeId 属性上,但随后我收到有关依赖/主关系约束的错误,并且我不确定如何将类别指定为附加外键。

我还没有找到一个关于表/继承的教程,它在我使用它们时会遍历导航属性。任何帮助将不胜感激,这已经让我发疯了一个多小时。

更新:

我认为问题在于使用 Category 作为 key 的一部分。 CardSet 没有用于该查找的“游戏”类别或用于该查找的“设置类型”类别的两个属性。我尝试创建这些属性,但没有奏效。是否可以使用 Fluent API 进行设置?到目前为止,我已经做了十几次尝试,但都没有运气。

【问题讨论】:

    标签: entity-framework navigation-properties table-per-hierarchy


    【解决方案1】:

    我认为 EF 不“喜欢”构造 modelBuilder.Entity&lt;Lookup&gt;() 来映射两个子类。这应该会有所帮助:

    modelBuilder.Entity<Game>()
      .Map(l => l.Requires("LookupType").HasValue("Game"));
    modelBuilder.Entity<SetType>()
      .Map(l => l.Requires("LookupType").HasValue("Set Type"));
    

    【讨论】:

    • 我真的希望它会这么简单。您的建议向我抛出了一组不同的验证错误:在模型生成期间检测到一个或多个验证错误:System.Data.Entity.Edm.EdmAssociationConstraint:关系约束中的从属角色和主体角色中的属性数量必须相同。但是教程link 显示了使用基类的实体。
    • 你是对的!所以我尝试了你的模型,没有得到任何错误。给定的代码有效(EF 5、VS2012、.Net4.5)。在我的上下文中,我只有一个 DbSet&lt;Lookup&gt; 和一个 DbSet&lt;CardSet&gt;。为简单起见,您还遗漏了任何其他类吗?顺便说一句,如果我们在这方面取得任何进展,我会删除这个答案,或者编辑它。
    • 我有一个带有完整模型的单独项目,但是当我执行此操作时,即使是带有上述模型的更简单的项目也不起作用:_dataContext.Dictionary.Where(l => l.Category == categoryName && l.IsActive == activeOnly); categoryName = "游戏" and activeOnly = true
    • 是的,我运气不好。我尝试了一种解决方法,将 Category 从 Key 中删除并将其设置为 required,但这不适用于我的较大模型。