【问题标题】:TPC mapping: MapInheritedProperties() force key inheritanceTPC 映射:MapInheritedProperties() 强制键继承
【发布时间】:2015-02-06 18:58:44
【问题描述】:

问题是孩子的 PK 是父母的密钥,尽管我们已经修改(使用了每个类映射的表)。

public class Entity
{
    [Key]
    public Guid EntityId { get; set; }    
}

public class VersionedEntity: Entity
{
    public Guid VersionId { get; set; }    
}

OnModelCreating 包含:

modelBuilder.Entity<VersionedEntity>().Map(m =>
{
   m.MapInheritedProperties();
});
modelBuilder.Entity<VersionedEntity>().HasKey(e => new { e.EntityId , e.HistoryId});

因此,我们将获得仍包含单列 PK (EntityId) 的 VersionedEntity。

在 m.MapInheritedProperties() 替换/删除“继承的”父键映射之后,我们是否有可能?

【问题讨论】:

    标签: entity-framework inheritance entity-framework-6


    【解决方案1】:

    不,你没有。原因是 EF 对整个继承树都有一个实体键定义。在我看来,它甚至应该为第二个 HasKey 语句抛出错误,而不是默默地忽略它。

    拥有一个实体键定义的原因是您可能(但可能不会)通过一个DbSet&lt;Entity&gt; 公开所有实体。如果是这样,应该可以做到……

    context.Entities.Find(Guid.Parse(someGuid));
    

    如果一个子类型有不同类型的键,这是不可能的。

    如果您需要继续使用此模型,最好让 EF 忽略基类并单独映射每种类型,而不使用映射继承。在这种情况下,base EntityTypeConfiguration 可能会有所帮助。

    【讨论】:

    • 谢谢。我对你的回答很满意,但不幸的是,我在你的解释中遗漏了一些重要的东西。我想保留一把钥匙,不用解释我为什么需要一把钥匙。但我对访问我们保存“键定义”并从该结构中删除“继承键”的结构的可能性很感兴趣。
    • 好吧,这有点不同。我猜从技术上讲,TPC 继承中的两个类可以有不同的关键字段名称,只要字段的数量、顺序和类型完全匹配。 EF只是不支持。我无法想象具有可变数量字段的键如何适合一个继承层次结构。
    • 正如您在结构上看到的那样,二级键适合(我可以创建第二个)。所以我搜索的内容是:找到应该位于模型构建器深处某处的“键”数组,并删除与子实体关联的一个键(在 MapInheritedProperties 上创建)。然后我将能够创建新密钥。有意义吗?
    • 坦率地说,没有。 EF 应该始终能够通过相同的唯一键标识派生类的 所有 对象实例。如果您能够以某种方式添加第二个键属性,EntityId 值可能会重复,并且 EF 会抛出重复键异常。您的案例没有实施。 也许 EF 可以比较 TPC 中每种类型的键值 - 但它不能。
    • 我只知道HasKey(e =&gt; new { e.EntityId , e.HistoryId})
    猜你喜欢
    • 1970-01-01
    • 2013-03-04
    • 2015-09-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-07
    • 2011-11-22
    • 2010-11-25
    相关资源
    最近更新 更多