EFmanual/dynamictable报名

EF manual/dynamic table registration

我正在尝试手动创建一些 table 并动态映射到 DbSet,但它不起作用。这是我的 DbContext class:

public abstract class DynamicDbContext : DbContext
{
    private List<IQueryable> m_dbSets;

    public DynamicDbContext([NotNull] DbContextOptions options) :
        base(options)
    {
    }

    public DbSet<T> GetTbl<T>() where T : class
    {
        if (m_dbSets == null)
        {
            m_dbSets = new List<IQueryable>();

            foreach (var iter in GetDynTypes())
            {
                var setMethod = typeof(DbContext).GetMethod(nameof(DbContext.Set), new[] { typeof(string) });
                IQueryable foundSet = (IQueryable)setMethod
                    .MakeGenericMethod(iter)
                    .Invoke(this, new object[] { iter.Name });

                    m_dbSets.Add(foundSet);
                }
            }
        }

        return m_dbSets.FirstOrDefault(obj => obj.ElementType == typeof(T)) as DbSet<T>;
    }
    
    protected abstract List<Type> GetDynTypes();

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

        foreach (var iter in GetDynTypes())
        {
            EntityTypeBuilder builder = modelBuilder.Entity(iter);
            builder.ToTable(iter.Name);
        }
    }
    #endregion
}

class 从应用程序派生的 class 获取动态类型,并且应该将 classes 作为 tables 注册到数据库。然后我想使用 Linq 来处理 tables,所以我引入了 GetTbl 方法,该方法将 return DbSet<T> 以便应用程序可以在此集合上调用 Linq。此方法使用反射获取DbSet,但我也试过直接调用Set<T>(typeof(T).Name)

当我尝试访问 returned DbSet 时,结果异常: 无法为 'Abc' 创建 DbSet,因为此类型未包含在上下文模型中

看起来 table(s) 已创建,例如当我 运行 迁移命令时,我可以在数据库中看到 tables:

dotnet ef migrations add InitialCreate

问题可能出在 table 映射到 DbSet - 在我的 GetTbl 方法中。或者我可能需要在 OnModelCreating 方法中做一些额外的事情。

不确定是什么问题。任何帮助表示赞赏:-) 谢谢

一旦您在 OnModelCreating 中注册了类型,您就可以通过

简单地获取 DbSet
 myDbContext.Set<T>();

因此,更简单的设计是仅使用您在运行时使用动态实体类型专门化的单一泛型类型。例如

public class DynamicDbContext<T> : DbContext where T:class
{
    public DynamicDbContext([NotNull] DbContextOptions options) :
        base(options)
    {
    }

    public DbSet<T> Entities => this.Set<T>();

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<T>().ToTable(typeof(T).Name);
        base.OnModelCreating(modelBuilder);
    }
}

当然这不会创建 table 如果它不存在。