已动态注册DbSet到DbContext,如何向表中添加数据?
动态注册实体后无法通过DbContext属性访问DbSet的解决办法
你已经通过扩展方法在OnModelCreating里完成了实体的动态注册,迁移功能正常,但因为ApplicationDbContext里没有显式声明DbSet<Client>这类属性,所以没法用context.Client.Add(client)的方式操作实体。下面是几种可行的解决办法:
方法1:用泛型Set<TEntity>直接操作
这是最省事的替代方案,不需要修改DbContext,直接用EF Core内置的泛型方法:
// 替换原来的 context.Client.Add(client) context.Set<Client>().Add(client); await context.SaveChangesAsync();
只要Client继承了对应的BaseEntity,就能被EF Core正常识别,和显式声明DbSet的效果完全一致。
方法2:给DbContext加泛型DbSet属性
如果习惯用属性访问的写法,可以在ApplicationDbContext里添加泛型属性:
public class ApplicationDbContext : DbContext { // 针对int主键的实体 public DbSet<TEntity> Set<TEntity>() where TEntity : BaseEntity<int> { return base.Set<TEntity>(); } // 针对Guid主键的实体 public DbSet<TEntity> SetGuid<TEntity>() where TEntity : BaseEntity<Guid> { return base.Set<TEntity>(); } // 原有的OnModelCreating代码... }
调用时就可以写成:
context.Set<Client>().Add(client); // Guid主键的实体用这个 context.SetGuid<Order>().Add(order);
方法3:动态生成强类型DbSet属性(进阶)
如果一定要让DbContext拥有Client、Order这类强类型属性,可以用源码生成工具自动生成:
- 用Roslyn源码生成器扫描实体所在程序集,找出所有继承自
BaseEntity<int>和BaseEntity<Guid>的类型。 - 自动生成
ApplicationDbContext的部分类,添加对应的DbSet属性:
public partial class ApplicationDbContext : DbContext { public DbSet<Client> Client { get; set; } public DbSet<Order> Order { get; set; } // 其他实体的DbSet属性... }
这种方式兼顾了动态注册的简洁性和强类型属性的便利,但需要额外配置源码生成的逻辑。
内容的提问来源于stack exchange,提问作者zahra liaghatmand
相关产品推荐
相关产品推荐

