将 Entity Framework Core 中的继承结构映射到 Postgres - 冲突的错误消息

Mapping inheritance structure in Entity Framework Core to Postgres - Conflicting Error Messages

我的模型中有许多继承层次结构。我将 Entity Framework Core 3.1.2 与 Postgres 数据库一起使用。代码优先。我正在尝试创建迁移以生成我的数据库表。

我映射了我的第一个摘要object

public DbSet<Asset> Assets { get; set; }

我了解到,如果不映射具体的后代,就无法映射抽象 class。

The corresponding CLR type for entity type 'Asset' is not instantiable and there is no derived entity type in the model that corresponds to a concrete CLR type.

所以我映射后代。

public DbSet<LinearAsset> LinearAssets { get; set; }
public DbSet<StructureAsset> Structures { get; set; }
public DbSet<BridgeAsset> Bridges { get; set; }
public DbSet<RoadAsset> Roads { get; set; }

一切都很好。太棒了。

不过。当我开始映射我的第二个继承层次结构(以及我尝试的任何其他继承层次结构)时,我陷入了这个奇怪的循环论证,我必须和不能映射 children.

public DbSet<Attachment> Attachments { get; set; }
public DbSet<AssetAttachment> AssetAttachments { get; set; }

给我

The entity type 'AssetAttachment' cannot be mapped to a table because it is derived from 'Attachment'. Only base entity types can be mapped to a table.

如果我删除 AssetAttachments 的映射,我会回到这个

The corresponding CLR type for entity type 'Attachment' is not instantiable and there is no derived entity type in the model that corresponds to a concrete CLR type.

我没能在有效的资产继承层次结构和其他无效的继承层次结构之间找到任何有意义的区别。

我尝试了各种不同的映射方式,或者不映射后代 objects,但它总是返回到上述两个错误消息之一。 我既要映射也不要映射后代,这让我很困惑 Dot Net 到底想从我这里得到什么。

有人能给我一些建议,告诉我如何处理这两个相互矛盾的错误消息吗?

事实证明,问题是我将 table 名称转换为蛇形,以符合 postgres 约定。使字段名称蛇形大小写很好,但是使 table 名称蛇形大小写引入了我上面描述的错误。

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        foreach (var entity in modelBuilder.Model.GetEntityTypes())
        {
            // THIS IS WHAT CAUSES THE ISSUE
            if (!String.IsNullOrWhiteSpace(entity.GetTableName()) && (entity.GetTableName() != entity.GetTableName().ToLower()))
                entity.SetTableName(ToSnakeCase(entity.GetTableName()));

            // THIS IS OKAY
            foreach (var property in entity.GetProperties())
            {
                property.SetColumnName(ToSnakeCase(property.GetColumnName()));
            }
        }
        base.OnModelCreating(modelBuilder);
    }