使用dotnet ef dbcontext scaffold生成模型时如何跳过指定列?
实现方案
可以通过数据库元数据标记配合自定义Scaffold处理逻辑实现指定列跳过生成,具体实现路径如下:
第一步:给需要跳过的列添加元数据标记
不同数据库可以选择对应的元数据存储方式:- SQL Server:使用扩展属性标记,示例SQL如下:
EXEC sp_addextendedproperty @name = N'ScaffoldSkip', @value = 1, @level0type = N'Schema', @level0name = 'dbo', @level1type = N'Table', @level1name = '目标表名', @level2type = N'Column', @level2name = '要跳过的列名'; - MySQL/PostgreSQL:可以在列注释中加入特殊标识,比如注释内容添加
[ScaffoldSkip]字符串作为识别标记。
- SQL Server:使用扩展属性标记,示例SQL如下:
第二步:自定义EF Core Scaffold的模型生成逻辑
实现IModelCustomizer接口,在模型生成阶段读取元数据标记,移除对应列的映射:- 新建类库项目,引用
Microsoft.EntityFrameworkCore.Design包和对应数据库的EF Core提供器包 - 实现自定义模型定制器:
public class SkipColumnModelCustomizer : RelationalModelCustomizer { public SkipColumnModelCustomizer(ModelCustomizerDependencies dependencies, RelationalModelCustomizerDependencies relationalDependencies) : base(dependencies, relationalDependencies) { } public override void Customize(ModelBuilder modelBuilder, DbContext context) { base.Customize(modelBuilder, context); // 读取数据库中所有标记为跳过的表+列组合 var skipColumnList = GetSkipColumnsByMetadata(context.Database.GetDbConnection()); foreach (var entityType in modelBuilder.Model.GetEntityTypes()) { var currentTableName = entityType.GetTableName(); var columnsToSkip = skipColumnList.Where(c => c.TableName == currentTableName).ToList(); foreach (var skipCol in columnsToSkip) { var targetProperty = entityType.FindProperty(skipCol.ColumnName); if (targetProperty != null) { entityType.RemoveProperty(targetProperty); } } } } // 根据数据库类型实现元数据查询逻辑,返回所有要跳过的列集合 private List<(string TableName, string ColumnName)> GetSkipColumnsByMetadata(DbConnection connection) { // 示例:SQL Server下查询带ScaffoldSkip扩展属性的列 // MySQL下查询列注释包含[ScaffoldSkip]的列即可 } }- 实现
IDesignTimeServices接口注册自定义服务:
public class DesignTimeServices : IDesignTimeServices { public void ConfigureDesignTimeServices(IServiceCollection serviceCollection) { serviceCollection.AddSingleton<IModelCustomizer, SkipColumnModelCustomizer>(); } }- 新建类库项目,引用
第三步:执行Scaffold命令时指定自定义服务所在程序集
命令示例:dotnet ef dbcontext scaffold "你的数据库连接串" Microsoft.EntityFrameworkCore.SqlServer --project 模型输出项目路径 --design-time-project 自定义类库项目路径
如果场景不需要动态适配不同数据库,也可以直接使用EF Core原生的T4模板自定义生成逻辑,硬编码要跳过的列列表,实现成本更低。
内容的提问来源于stack exchange,提问作者Thorbjørn Ravn Andersen
相关产品推荐
相关产品推荐

