如何在 Entity Framework Core 中结合使用自定义表前缀和 TPH?

问题描述 投票:0回答:1

免责声明:我在 C# / WPF / EFC 方面相对缺乏经验

我正在开发一个用 C# 编写的 WPF 应用程序,它需要在数据库中存储一些数据。为了存储这些数据,我想使用 Entity Framework Core。该应用程序将使用一个共享数据库实例,其他应用程序也使用该实例。每个应用程序都有自己的表前缀,因此我的应用程序也需要有自己的表前缀。

更新

我想要实现的是从

Parent
继承的所有对象都存储在同一个表中。当我从表中“加载”数据时,我想要一个有关
Child
类的实例化实例。本身不可能/不应该有
Parent
的实例。

添加表前缀

我在我的

OnModelCreating
类的
DbContext
函数中添加了表前缀(到目前为止效果很好):

foreach (var entity in modelBuilder.Model.GetEntityTypes())
{
    modelBuilder.Entity(entity.ClrType).ToTable(tablePrefix + entity.GetTableName());
}

实现“每个层次结构表”

实现表前缀后,我根据这个描述实现了TPHhttps://www.learnentityframeworkcore.com/inheritance/table-per-hierarchy

这是实现:

public abstract class Parent
{
    // ...
}

public class ChildA : Parent
{
    // ...
}

public class ChildB : Parent
{
    // ...
}

internal class EcroDbContext : DbContext
{
    private string tablePrefix = "APP_PREFIX_";

    public DbSet<Schedule> Schedules { get; set; } = null;

    public DbSet<ChildA> ChildA { get; set; } = null;
    public DbSet<ChildBIpp> ChildB { get; set; } = null;

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        string user = "xxx";
        string password = "xxx";
        string dbName = "xxx";
        string conString = "User Id=" + user + ";Password=" + password + ";Data Source=" + dbName;

        optionsBuilder.UseOracle(conString, x => x.MigrationsHistoryTable(tablePrefix + "ef_migration_history", null));
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        modelBuilder.Entity<Parent>().ToTable(tablePrefix + "Jobs");

        // Add prefix to each table.
        // When I remove this foreach, the TPH works fine
        foreach (var entity in modelBuilder.Model.GetEntityTypes())
        {
            modelBuilder.Entity(entity.ClrType).ToTable(tablePrefix + entity.GetTableName());
        }
    }
}

当我运行

Add-Migration InitialMigration
时,我收到此错误:

无法创建类型为“”的“DbContext”。异常“‘ChildB’和‘ChildA’都映射到表‘APP_PREFIX_APP_PREFIX_APP_PREFIX_Jobs’。非 TPH 层次结构(没有鉴别器的层次结构)中的所有实体类型必须映射到不同的表。

错误指出“非 TPH 中的所有实体类型必须映射不同的表”,但我认为我已经为上述类实现了 TPH。首先我以为我实现了错误,但是当我从

OnModelCreating
部分中删除表前缀部分时,它似乎工作正常。

这意味着表前缀实现会导致

TPH
实现出现问题。我该如何解决这个错误?

[已解决]

我注意到

Jobs
表的前缀添加了 3 次。我该如何解决这个问题?

c# oracle entity-framework-core table-per-hierarchy
1个回答
0
投票

我通过检查名称是否已包含前缀(如 @ Svyatoslav Danyliv 建议)。

            foreach (var entity in (modelBuilder.Model.GetEntityTypes()))
            {
                if (!entity.GetTableName().Contains(tablePrefix))
                {
                    modelBuilder.Entity(entity.ClrType).ToTable(tablePrefix + entity.GetTableName());
                }
            }

这也因某种原因解决了TPH问题。现在它就像一个魅力。

© www.soinside.com 2019 - 2024. All rights reserved.