1. 项目概述:SmartDapper.UI 数据库实体生成工具
最近在重构一个老项目时,发现手动编写数据库实体类的工作量巨大且容易出错。正好接触到SmartDapper.UI这个工具,它能够直接从数据库结构反向生成C#实体类,大幅提升了开发效率。这个工具特别适合.NET开发者使用Dapper进行数据访问的场景。
SmartDapper.UI的核心功能是通过可视化界面连接数据库,自动分析表结构并生成对应的POCO类。与传统的Entity Framework不同,它生成的实体类更加轻量级,完全适配Dapper的简单、高效特性。我在实际项目中使用后发现,原本需要半天时间的手工编码工作,现在只需几分钟就能完成。
2. 核心功能解析
2.1 数据库连接与结构分析
SmartDapper.UI支持多种主流数据库:
- SQL Server
- MySQL
- PostgreSQL
- Oracle
连接数据库时需要提供:
- 服务器地址/实例名
- 认证方式(Windows/账号密码)
- 数据库名称
- 可选的高级连接参数
连接成功后,工具会扫描数据库中的所有表、视图和存储过程,以树形结构展示。开发者可以自由选择需要生成实体的对象。
注意:生产环境连接建议使用只读账号,避免误操作风险
2.2 实体类生成配置选项
生成实体类前可以进行多项配置:
- 命名空间设置
- 是否使用partial类
- 是否生成注释(从表/列描述提取)
- 字段命名规则(PascalCase/camelCase)
- 是否包含FluentValidation验证规则
- 是否生成Dapper扩展方法
一个典型的生成配置示例:
// 生成选项 { "Namespace": "Domain.Entities", "UsePartial": true, "GenerateComments": true, "NamingConvention": "PascalCase", "IncludeValidations": false, "GenerateExtensions": true }2.3 生成结果示例
以简单的用户表为例,生成的实体类如下:
/// <summary> /// 用户信息表 /// </summary> public partial class User { /// <summary> /// 用户ID /// </summary> public int Id { get; set; } /// <summary> /// 用户名 /// </summary> public string UserName { get; set; } /// <summary> /// 密码哈希 /// </summary> public string PasswordHash { get; set; } /// <summary> /// 创建时间 /// </summary> public DateTime CreateTime { get; set; } } // 生成的扩展方法 public static class UserExtensions { public static async Task<User> GetByIdAsync(this IDbConnection conn, int id) { return await conn.QueryFirstOrDefaultAsync<User>( "SELECT * FROM [User] WHERE Id = @id", new { id }); } }3. 技术实现原理
3.1 数据库元数据查询
工具通过各数据库提供的系统表/视图获取结构信息:
- SQL Server: INFORMATION_SCHEMA + sys 系统表
- MySQL: INFORMATION_SCHEMA
- PostgreSQL: pg_catalog + information_schema
- Oracle: ALL_TABLES/ALL_TAB_COLUMNS
核心查询示例(SQL Server):
SELECT t.name AS TableName, c.name AS ColumnName, ty.name AS DataType, c.max_length AS MaxLength, c.is_nullable AS IsNullable, ep.value AS Description FROM sys.tables t INNER JOIN sys.columns c ON t.object_id = c.object_id INNER JOIN sys.types ty ON c.user_type_id = ty.user_type_id LEFT JOIN sys.extended_properties ep ON ep.major_id = t.object_id AND ep.minor_id = c.column_id AND ep.name = 'MS_Description' WHERE t.is_ms_shipped = 03.2 类型映射系统
数据库类型到C#类型的映射是核心功能之一。SmartDapper.UI内置了完善的类型映射表:
| 数据库类型 | C#类型 | 特殊处理 |
|---|---|---|
| int | int | |
| bigint | long | |
| varchar/nvarchar | string | 根据MaxLength生成StringLength |
| datetime | DateTime | |
| decimal | decimal | 保留精度和小数位设置 |
| bit | bool | |
| uniqueidentifier | Guid |
提示:可以在设置中自定义类型映射规则
3.3 代码生成引擎
采用T4模板引擎生成代码,模板分为:
- 实体类模板
- 扩展方法模板
- 验证规则模板(可选)
实体类模板示例:
<#@ template language="C#" #> <#@ import namespace="System.Collections.Generic" #> <#@ import namespace="SmartDapper.UI.Models" #> <# foreach(var table in Tables) { #> /// <summary> /// <#= table.Description #> /// </summary> public partial class <#= table.ClassName #> { <# foreach(var column in table.Columns) { #> /// <summary> /// <#= column.Description #> /// </summary> public <#= column.CSharpType #> <#= column.PropertyName #> { get; set; } <# } #> } <# } #>4. 高级功能与技巧
4.1 自定义模板功能
在安装目录的Templates文件夹中可以找到所有模板文件,开发者可以:
- 修改现有模板调整生成风格
- 添加新模板支持更多场景
- 创建项目特定模板
常见的自定义场景包括:
- 添加特定的属性注解(如Swagger/Newtonsoft.Json)
- 生成gRPC消息定义
- 生成GraphQL类型
- 添加审计字段支持
4.2 批量生成与更新策略
处理大型数据库时建议:
- 先选择少量表测试生成结果
- 使用"仅生成新表"模式避免覆盖已有实体
- 设置输出目录为源码管理下的文件夹
- 使用"对比差异"功能查看变更
经验:将生成的代码放入单独项目/DLL,避免频繁重新生成影响业务代码
4.3 与Dapper的最佳实践结合
生成的实体类可以完美配合Dapper使用:
- 查询结果直接映射到实体
- 参数化查询使用匿名对象
- 事务操作使用相同连接
- 多表查询使用QueryMultiple
示例用法:
public class UserRepository { private readonly IDbConnection _conn; public UserRepository(IDbConnection conn) { _conn = conn; } public async Task<User> GetUserWithRoles(int userId) { using var multi = await _conn.QueryMultipleAsync( "SELECT * FROM [User] WHERE Id = @id; " + "SELECT r.* FROM [Role] r " + "INNER JOIN [UserRole] ur ON r.Id = ur.RoleId " + "WHERE ur.UserId = @id", new { id = userId }); var user = await multi.ReadFirstOrDefaultAsync<User>(); if(user != null) { user.Roles = (await multi.ReadAsync<Role>()).ToList(); } return user; } }5. 常见问题与解决方案
5.1 连接问题排查
| 问题现象 | 可能原因 | 解决方案 |
|---|---|---|
| 连接超时 | 网络不通/防火墙阻止 | 检查端口开放情况 |
| 认证失败 | 账号权限不足 | 使用具有元数据读取权限的账号 |
| 找不到数据库 | 数据库名称错误 | 检查数据库名称大小写 |
| 驱动程序未加载 | 缺少对应数据库客户端驱动 | 安装对应数据库的.NET驱动 |
5.2 生成代码问题
问题1:生成的属性名称不符合团队规范
解决方案:
- 修改工具设置中的命名规则
- 使用自定义模板添加特定前缀/后缀
- 通过正则表达式替换批量修改
问题2:枚举类型未正确识别
解决方案:
- 手动创建枚举定义
- 在模板中添加条件生成逻辑
- 通过命名约定自动识别(如Type结尾的字段)
问题3:复杂类型处理不当
对于JSON/XML字段:
- 自定义类型转换器
- 生成时添加适当的注解
[Column(TypeName = "jsonb")] public Address ShippingAddress { get; set; }5.3 性能优化建议
对于大型数据库:
- 分批次生成(按schema/前缀过滤)
- 关闭实时预览功能
- 增加连接超时时间
- 在非高峰期执行生成操作
实测数据(基于SQL Server):
- 100张表:约3秒
- 500张表:约15秒
- 1000张表:约40秒
6. 替代方案比较
6.1 与Entity Framework对比
| 特性 | SmartDapper.UI | Entity Framework |
|---|---|---|
| 生成代码类型 | 纯净POCO | 包含EF特性 |
| 运行时性能 | 更高 | 较低 |
| 学习曲线 | 简单 | 较复杂 |
| 灵活性 | 高 | 中等 |
| 适合场景 | 微服务/高性能需求 | 快速开发/复杂查询 |
6.2 其他类似工具
PocoGen:
- 优点:支持更多数据库类型
- 缺点:界面较旧,模板功能弱
EF Core Power Tools:
- 优点:深度集成Visual Studio
- 缺点:仅支持EF Core
自定义T4模板:
- 优点:完全可控
- 缺点:维护成本高
在实际项目中,我通常会根据团队技术栈选择工具。对于纯Dapper项目,SmartDapper.UI提供了最佳的平衡点。它的可视化界面让非核心开发人员也能参与数据模型维护,而自定义模板功能则满足了架构师对代码规范的要求。