【问题标题】:Derived POCOs referencing same table - strange naming issues引用同一张表的派生 POCO - 奇怪的命名问题
【发布时间】:2015-05-16 08:49:44
【问题描述】:

我有一个“基础”实体,其中一些属性被一些共享库中的一堆其他东西(存储库模式、队列等)使用。映射到复数表。

我需要为我的具体实现添加一个属性,并且我想重用所有其余的正常行为。

我派生一个类:

public interface IItem {
    [Key]
    Guid Id { get; set; }
    string Name { get; set; }
}

public class Item : IItem {
    [Key]
    public Guid Id { get; set; }
    public string Name { get; set; }
}

public interface IExtended {
    bool IsExtended { get; set; }
}

[Table("Items")]        // <-- my nemesis
public class ExtendedItem : Item, IExtended {
    [Column("_Extended")]
    public bool IsExtended { get; set; }
}

我设置了代码优先上下文:

public class MyContext : DbContext {
    public MyContext(string connectionString) : base(connectionString) {
        // manually creating the tables, no migrations
        Database.SetInitializer<EfQueueContext>(null);
    }

    public DbSet<Item> Items { get; set; }
}
  • 没有 DataAnnotation [Table] 我得到异常“无效的列名 'Discriminator'”——好的,很奇怪,但是 makes sense
  • [NotMapped] 出现异常“实体类型 ExtendedItem 不是当前上下文模型的一部分”--好的,有道理
  • 使用注释 [Table("Item"] 我得到异常“表 'dbo.Item' 不存在”——好吧,忘了它的复数形式
  • 使用注释 [Table("Items")] 我得到异常“表 'dbo.Items1' 不存在” -- 什么??? 1 后缀从何而来?
  • 即使创建一个仅引用 ExtendedItem 而不是 Item 的全新 DbContext 仍然添加“1” (更新 - 我实际上并没有创建一个干净的实例;请参阅对答案的评论)

【问题讨论】:

  • 如果你使用[Table("Something")]而不是“项目”呢?它可能只是与 Item 类冲突。
  • 我相信class Item 收到表名Items。所以对于class ExtendedItem,它应该是别的东西,比如ExtendedItems
  • 好的,我明白了。所以你想把Item和ExtendedItem保持在同一个表Items中?确保 EF 支持您希望它的工作方式。这里不确定。
  • 反正名字冲突的根源是Item类缺少注解,所以它会自动接收一个复数名字Items。
  • @abatishchev 您应该能够使用 annotations/fluent-api 手动指定表名,但我真正的问题是,当我指定确切的现有表名(“Items”)时决定附加一个“1”而不是使用我告诉它的内容。我稍微更新了这个问题以强调这个问题。

标签: c# entity-framework


【解决方案1】:

问题是当您在子类上应用Table 属性以指定映射表名称时,EF 推断您想要创建一个Table per Type (TPT)。在您的情况下,您正在尝试重命名与ExtendedItem 实体相关的表,但您使用的是与根表相同的名称,这就是 EF 创建两个表的方式,其中一个名为 Items1(因为您已经使用了 @987654326继承实体中的@name)与Item实体相关,另一个名为ItemsExtentedItem实体相关

如果你想创建一个Table per Hierarchy (TPH)并且你想重命名根表,那么你需要在根实体(Item)和所有继承它的实体上应用[Table("Items")]数据注解。

【讨论】:

  • 这听起来不错——我实际上并没有尝试过,因为我发现我不小心继承了原来的MyContext,而不是来自DbContext,这意味着Item 和@987654335 @是DbSets。一旦我从一个没有声明Item 的新DbContext 开始,我只需要重命名ExtendedItem
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-05-26
  • 2019-12-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-24
相关资源
最近更新 更多