EF手动/动态表注册
Posted
技术标签:
【中文标题】EF手动/动态表注册【英文标题】:EF manual/dynamic table registration 【发布时间】:2021-08-19 10:49:48 【问题描述】:我正在尝试手动创建一些表并动态映射到DbSet
,但它不起作用。这是我的DbContext
课程:
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
该类从应用程序的派生类中获取动态类型,并应将这些类作为表注册到数据库中。然后我想使用 Linq 来处理表格,所以我引入了 GetTbl
方法,该方法将返回 DbSet<T>
以便应用程序可以在此集合上调用 Linq。这个方法使用反射来获取DbSet
,不过我也试过直接调用Set<T>(typeof(T).Name)
。
当我尝试访问返回的 DbSet 时,结果是异常: 无法为“Abc”创建 DbSet,因为该类型未包含在上下文模型中
看起来表是创建的,例如当我运行迁移命令时,我可以看到数据库中的表:
dotnet ef migrations add InitialCreate
问题可能在于表映射到DbSet
- 在我的GetTbl
方法中。或者我可能需要在 OnModelCreating
方法中做一些额外的事情。
不确定是什么问题。任何帮助表示赞赏:-) 谢谢
【问题讨论】:
请看***.com/questions/38532764/… 这能回答你的问题吗? Create Tables on runtime in EF Core 不幸的是,这没有帮助。检查我的数据库,创建了表,但是我无法在我的 GetTbl 方法中动态地将表映射到 DbSet。 在 OnModelCreating 中注册类型后,只需myDbContext.Set<T>();
即可获取 DbSet
【参考方案1】:
在 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);
如果表不存在,当然不会创建表。
【讨论】:
这行得通。有趣的是我的代码很相似但它不起作用 - 神奇:-)以上是关于EF手动/动态表注册的主要内容,如果未能解决你的问题,请参考以下文章