1. 为什么.NET开发者需要"CRUD填空题"神器?
作为一名常年混迹外包项目的.NET老鸟,我经历过太多重复劳动——每次新项目启动,都要从零开始搭建权限管理、设计基础表结构、编写增删改查接口。直到去年接手某政务系统项目时,甲方要求在两周内交付包含87张业务表的原型系统,被逼无奈下我开发了这套"填空题式CRUD生成器"。
传统开发模式下,完成一个标准业务模块需要:
- 创建Entity类(30分钟)
- 编写DbContext配置(15分钟)
- 实现Repository层(1小时)
- 开发Service层(2小时)
- 编写Controller接口(1.5小时)
- 制作前端页面(3小时)
而使用本文方案后,只需:
- 定义JSON格式的字段描述(10分钟)
- 运行代码生成命令(30秒)
- 微调特殊业务逻辑(可选)
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 核心架构设计思路
2.1 三层生成引擎联动机制
这套系统的核心在于三个生成引擎的协同工作:
mermaid复制graph TD
A[动态表单引擎] -->|生成JSON Schema| B[代码生成引擎]
B -->|输出C#代码| C[模板引擎]
C -->|渲染| D[最终代码文件]
(注:实际实现时用Roslyn替代了模板引擎)
2.2 关键技术选型对比
| 技术点 | 候选方案 | 最终选择 | 选择理由 |
|---|---|---|---|
| 代码生成 | T4模板/Roslyn | Roslyn | 支持编译时检查,智能提示更友好 |
| 动态表单 | ElementUI/ElPlus | ElPlus | 对.NET生态兼容性更好,表单校验规则更灵活 |
| 流程引擎 | Flowable/WorkflowCore | WorkflowCore | 纯.NET实现,避免Java生态依赖 |
| ORM框架 | EF Core/Dapper | EF Core | 与.NET6深度集成,DbContext生成更便捷 |
3. 手把手实现生成器核心
3.1 定义领域模型描述文件
创建template.json作为生成蓝图:
json复制{
"ModuleName": "OrderManagement",
"Entities": [
{
"Name": "Order",
"DisplayName": "订单",
"Properties": [
{
"Name": "OrderNo",
"Type": "string",
"Required": true,
"MaxLength": 32,
"FormItem": {
"Component": "el-input",
"Rules": [{ "Required": true, "Message": "请输入订单编号" }]
}
}
]
}
]
}
3.2 编写Roslyn代码生成器
安装必要NuGet包:
bash复制dotnet add package Microsoft.CodeAnalysis.CSharp
dotnet add package Microsoft.CodeAnalysis.Analyzers
核心生成逻辑:
csharp复制// 动态编译Entity类
var entitySource = BuildEntitySource(template);
var compilation = CSharpCompilation.Create("DynamicAssembly")
.AddSyntaxTrees(CSharpSyntaxTree.ParseText(entitySource))
.AddReferences(MetadataReference.CreateFromFile(typeof(object).Assembly.Location));
using var ms = new MemoryStream();
var emitResult = compilation.Emit(ms);
if (!emitResult.Success)
{
// 处理编译错误
}
3.3 集成ElPlus动态表单
前端通过JSON Schema自动渲染表单:
javascript复制// 转换JSON为ElPlus配置
const formConfig = convertJsonToForm(template.Entities[0]);
4. 实战中的六个性能陷阱
-
DbContext生命周期:自动生成的Repository默认使用Scoped生命周期,在批量操作时需要手动创建独立实例
-
导航属性加载:生成的代码默认关闭延迟加载,建议通过
.Include()显式加载 -
动态编译内存泄漏:每次生成后需要调用
Collect()强制GC回收 -
表单校验性能:字段超过50个时,改用分组校验策略
-
流程引擎状态管理:WorkflowCore的持久化配置需要单独优化
-
Razor页面热重载:动态生成的Razor页面需要配置
IMvcBuilder.AddRazorRuntimeCompilation()
5. 进阶扩展方向
5.1 智能字段推断系统
通过分析数据库注释自动生成字段规则:
csharp复制// 从SQLServer获取列注释
var columns = await dbContext.Database.SqlQueryRaw<ColumnInfo>(
"SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = @table",
new SqlParameter("table", tableName));
5.2 低代码流程设计器
集成WorkflowCore的可视化设计:
javascript复制// 前端流程图配置
const flowDesigner = new WorkflowDesigner({
nodes: [
{ id: 1, name: '审批节点', type: 'approval' }
]
});
5.3 多版本代码生成
支持同时输出.NET6和.NET8风格的代码:
csharp复制// 条件编译
#if NET6_0
services.AddControllersWithViews();
#elif NET8_0
var builder = WebApplication.CreateBuilder(args);
#endif
这套系统在我团队已经稳定运行9个月,累计生成代码超过20万行。最惊喜的是某次客户临时增加需求,原本需要3天的工作量,调整模板后仅用15分钟就完成了全部模块的重新生成。对于需要快速交付的中小型项目,这种"填空题"开发模式确实能大幅提升摸鱼...啊不,是开发效率。
