EF Core中如何将视图以表形式创建用于测试数据库?
优雅解决EF Core测试库中模拟视图创建表的问题
方法一:在DbContext中动态修改模型配置
在OnModelCreating方法里,先执行自动生成的实体配置,再遍历所有实体,将配置为视图的实体改为表:
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata; protected override void OnModelCreating(ModelBuilder modelBuilder) { // 执行自动生成的实体配置(比如Scaffold生成的modelBuilder.Entity<>代码) base.OnModelCreating(modelBuilder); // 遍历所有实体,替换视图配置为表 foreach (var entityType in modelBuilder.Model.GetEntityTypes()) { var viewName = entityType.GetViewName(); if (!string.IsNullOrEmpty(viewName)) { // 清除视图标识,设置为同名表 entityType.SetViewName(null); entityType.ToTable(viewName); } } }
这个方法无需修改自动生成的代码,每次重新生成实体后直接生效,适合快速解决问题。
方法二:自定义反向工程模板(适合频繁生成实体的场景)
如果用Scaffold-DbContext命令生成实体,可以修改EF Core的反向工程模板(.tt文件),让生成的配置直接用ToTable而非ToView,或者根据环境动态切换:
- 在解决方案中找到自动生成的
*.Context.tt文件 - 找到模板中生成
ToView的代码段,通常类似:
if (entityType.IsView) { entityBuilder.ToView(entityType.ViewName); } else { entityBuilder.ToTable(entityType.GetTableName()); }
- 修改为强制生成
ToTable:
// 不管是表还是视图,都生成ToTable配置 entityBuilder.ToTable(entityType.IsView ? entityType.ViewName : entityType.GetTableName());
也可以添加环境判断,比如读取配置文件,在测试环境下生成ToTable,生产环境保留ToView。
方法三:使用扩展方法封装逻辑
封装一个扩展方法,让OnModelCreating中的代码更简洁:
public static class ModelBuilderExtensions { public static void ReplaceViewsWithTables(this ModelBuilder modelBuilder) { foreach (var entityType in modelBuilder.Model.GetEntityTypes()) { var viewName = entityType.GetViewName(); if (!string.IsNullOrEmpty(viewName)) { entityType.SetViewName(null); entityType.ToTable(viewName); } } } }
然后在OnModelCreating中调用:
protected override void OnModelCreating(ModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); modelBuilder.ReplaceViewsWithTables(); }
内容的提问来源于stack exchange,提问作者Jan Rothkegel
相关产品推荐
相关产品推荐

