SmartDapper.UI 是一个轻量级、现代化的 ASP.NET Core 中间件,提供可视化 Web 界面,用于从数据库自动生成 C# 实体类代码。支持 SQL ServerMySQL 数据库的 Schema 反向工程。

✨ 主要特性

  • 🎨 现代化 UI:精美的深色主题界面,无需任何前端框架依赖
  • 🔄 多数据库支持:自动识别 SQL Server 和 MySQL 数据库
  • 🚀 零配置启动:简单两行代码即可集成到项目中
  • 📁 智能文件管理:支持可视化文件夹树选择器,自动查找解决方案根目录
  • 🔒 安全可靠:支持访问令牌保护,限制输出路径防止任意文件写入
  • 🧹 软删除生成可控:支持开关“是否生成软删”(是否自动添加 [SoftDelete] 特性)
  • 📦 自动包管理:启用“自动添加软删除”且生成的实体包含 [SoftDelete] 时,自动安装 SmartDapper 包
  • 实时反馈:即时的日志输出和操作反馈
  • 🎯 精准映射:完整的数据库类型到 C# 类型映射
  • 🔍 智能过滤:支持表名搜索、批量选择等便捷操作

📦 安装

通过 NuGet 包管理器安装:

dotnet add package SmartDapper.UI

或者在 csproj 文件中添加:


🚀 快速开始

1. 注册服务和中间件

Program.cs 中添加以下代码:

using SmartDapper.UI.Extensions;

var builder = WebApplication.CreateBuilder(args);

// 注册 SmartDapper.UI 服务
builder.Services.AddSmartDapperUi(options =>
{
    // UI 访问路径(类似 /swagger)
    options.PathBase = "/smartdapper";
    
    // 输出根目录(实体文件生成的根路径,默认为当前目录)
    // options.OutputRootDirectory = Directory.GetCurrentDirectory();
    var solutionRoot = Directory.GetParent(builder.Environment.ContentRootPath)?.Parent?.FullName 
                      ?? builder.Environment.ContentRootPath;
    options.OutputRootDirectory = solutionRoot;
    
    // 可选:设置访问令牌(启用后需要在请求头中提供)
    // options.AccessToken = "your-secret-token";
});

var app = builder.Build();

// 启用 SmartDapper.UI 中间件
app.UseSmartDapperUi();

app.Run();

2. 启动应用并访问 UI

启动应用后,在浏览器中访问:

http://localhost:5000/smartdapper

3. 使用界面生成实体

  1. 输入数据库连接字符串(支持 SQL Server 和 MySQL)

  2. 点击"检测数据库类型"(可选,用于确认连接正确)

  3. 点击"加载表",系统会自动读取所有表

  4. 选择要生成的表(支持搜索、全选、反选)

  5. 配置输出选项

    • Schema(SQL Server 默认 dbo,MySQL 留空)
    • Namespace(命名空间)
    • 输出目录(可使用"浏览..."按钮选择)
    • 是否覆盖已存在文件
    • 是否生成软删(自动添加软删除):关闭后即使检测到 IsDeleted 等软删列,也不会生成 [SoftDelete],也不会触发 SmartDapper 包自动安装
  6. 系统截图
    在这里插入图片描述

  7. 点击"生成实体"

📝 使用示例

SQL Server 示例

// Program.cs
builder.Services.AddSmartDapperUi(options =>
{
    options.PathBase = "/smartdapper";
    options.OutputRootDirectory = @"D:\MyProject";
});

在 UI 中输入:

  • 连接字符串Server=localhost;Database=MyDb;User Id=sa;Password=Pass123;TrustServerCertificate=True;
  • Schemadbo
  • NamespaceMyApp.Entities
  • 输出目录Models

生成的实体类示例:

using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace MyApp.Entities
{
    /// 
    /// 用户表
    /// 
    [Table("Users")]
    public class User
    {
        /// 
        /// 用户ID
        /// 
        [Key]
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public int Id { get; set; }

        /// 
        /// 用户名
        /// 
        [Required]
        [MaxLength(50)]
        public string Username { get; set; } = string.Empty;

        /// 
        /// 邮箱
        /// 
        [MaxLength(100)]
        public string? Email { get; set; }

        /// 
        /// 创建时间
        /// 
        public DateTime CreatedAt { get; set; }
    }
}

MySQL 示例

// Program.cs
builder.Services.AddSmartDapperUi(options =>
{
    options.PathBase = "/smartdapper";
    options.OutputRootDirectory = @"/home/user/projects/MyProject";
});

在 UI 中输入:

  • 连接字符串Server=localhost;Port=3306;Database=mydb;User=root;Password=pass;SslMode=None;
  • Schema:留空(MySQL 使用 Database 作为 Schema)
  • NamespaceMyApp.Entities
  • 输出目录Models

⚙️ 配置选项

SmartDapperUiOptions

属性 类型 默认值 说明
PathBase string /smartdapper UI 的访问路径前缀
OutputRootDirectory string 当前工作目录 实体文件生成的根目录,所有输出路径会被限制在此目录下
AccessToken string? null 可选的访问令牌,设置后需要在请求头 X-SmartDapper-Token 中提供

高级配置示例

builder.Services.AddSmartDapperUi(options =>
{
    // 自动查找解决方案根目录
    var solutionRoot = FindSolutionRoot(Directory.GetCurrentDirectory()) 
                      ?? Directory.GetCurrentDirectory();
    
    options.PathBase = "/code-generator";
    options.OutputRootDirectory = solutionRoot;
    options.AccessToken = builder.Configuration["SmartDapper:AccessToken"];
});

// 辅助方法:查找 .sln 文件所在目录
string? FindSolutionRoot(string startPath)
{
    var dir = new DirectoryInfo(startPath);
    while (dir != null)
    {
        if (dir.GetFiles("*.sln").Any())
            return dir.FullName;
        dir = dir.Parent;
    }
    return null;
}

🔐 安全配置

启用访问令牌保护

builder.Services.AddSmartDapperUi(options =>
{
    options.AccessToken = "your-secret-token-here";
});

客户端请求时需要添加请求头:

POST /smartdapper/api/generate HTTP/1.1
Host: localhost:5000
X-SmartDapper-Token: your-secret-token-here
Content-Type: application/json

开发环境 vs 生产环境

建议仅在开发环境启用 SmartDapper.UI:

var builder = WebApplication.CreateBuilder(args);

if (builder.Environment.IsDevelopment())
{
    builder.Services.AddSmartDapperUi(options =>
    {
        options.PathBase = "/smartdapper";
        options.OutputRootDirectory = FindSolutionRoot() ?? Directory.GetCurrentDirectory();
    });
}

var app = builder.Build();

if (app.Environment.IsDevelopment())
{
    app.UseSmartDapperUi();
}

app.Run();

🗄️ 数据库支持

连接字符串示例

SQL Server

Server=localhost;Database=MyDb;User Id=sa;Password=Pass123;TrustServerCertificate=True;
Server=.;Database=MyDb;Integrated Security=True;TrustServerCertificate=True;
Server=192.168.x.xxx,1433;Database=MyDb;User Id=sa;Password=Pass123;Encrypt=False;

MySQL

Server=localhost;Port=3306;Database=mydb;User=root;Password=pass;SslMode=None;
Server=192.168.x.xxx;Database=mydb;User=root;Password=pass;Charset=utf8mb4;

自动数据库类型识别

SmartDapper.UI 会根据连接字符串特征自动识别数据库类型:

数据库 识别特征
MySQL Port=3306, SslMode=, Charset=, AllowUserVariables=
SQL Server TrustServerCertificate=, Integrated Security=, Initial Catalog=, Data Source=

数据类型映射

点击展开完整映射表

整数类型

SQL Server MySQL C# 类型
TINYINT TINYINT byte
SMALLINT SMALLINT short
INT INT, INTEGER, MEDIUMINT int
BIGINT BIGINT long
BIT BIT bool

字符串类型

SQL Server MySQL C# 类型
VARCHAR VARCHAR string
NVARCHAR - string
CHAR CHAR string
NCHAR - string
TEXT TEXT, TINYTEXT, MEDIUMTEXT, LONGTEXT string
NTEXT - string
- ENUM string
- SET string
- JSON string

日期时间类型

SQL Server MySQL C# 类型
DATE DATE DateTime
DATETIME DATETIME DateTime
DATETIME2 - DateTime
SMALLDATETIME - DateTime
- TIMESTAMP DateTime
TIME TIME TimeSpan
- YEAR short
DATETIMEOFFSET - DateTimeOffset

数值类型

SQL Server MySQL C# 类型
DECIMAL DECIMAL decimal
NUMERIC NUMERIC decimal
MONEY - decimal
SMALLMONEY - decimal
FLOAT FLOAT float
REAL - float
- DOUBLE double

二进制类型

SQL Server MySQL C# 类型
BINARY BINARY byte[]
VARBINARY VARBINARY byte[]
IMAGE - byte[]
- BLOB, TINYBLOB, MEDIUMBLOB, LONGBLOB byte[]

特殊类型

SQL Server MySQL C# 类型
UNIQUEIDENTIFIER - Guid
XML - string
GEOGRAPHY - string
GEOMETRY - string

🎯 高级功能

自动安装 SmartDapper 包

当生成的实体类包含 [SoftDelete] 特性时(且 UI 勾选了“自动添加软删除”),SmartDapper.UI 会自动:

  1. 查找目标目录的 .csproj 文件
  2. 检查是否已安装 SmartDapper
  3. 如果未安装,自动添加包引用
  4. 在日志中提示安装结果

这样可以确保生成的代码直接可用,无需手动安装依赖。

软删除支持

SmartDapper.UI 会自动识别常见的软删除列并生成相应特性(默认开启,可在 UI 关闭“自动添加软删除 / 是否生成软删”):

[Table("Users")]
public class User
{
    [Key]
    public int Id { get; set; }
    
    public string Name { get; set; } = string.Empty;
    
    /// 
    /// 是否删除
    /// 
    [SoftDelete]
    public bool IsDeleted { get; set; }
}

支持的软删除列名(不区分大小写):

  • IsDeleted
  • IsDelete
  • Deleted
  • Del
  • DeleteFlag

文件夹树浏览器

UI 提供了内置的文件夹树浏览器,具有以下特性:

  • 🌲 树形结构:直观展示项目目录结构
  • 🔍 自动过滤:排除 binobjnode_modules.git 等无关目录
  • 📂 智能定位:自动查找解决方案根目录
  • 🎯 快速选择:点击文件夹图标或名称即可选择

📖 API 端点

SmartDapper.UI 提供了以下 REST API 端点(基于 PathBase 配置):

1. 检测数据库类型

POST /smartdapper/api/detect
Content-Type: application/json

{
  "connectionString": "Server=localhost;Database=test;..."
}

响应

{
  "databaseType": "MySQL",
  "message": "检测到 MySQL 数据库连接字符串"
}

2. 列出所有表

POST /smartdapper/api/tables
Content-Type: application/json

{
  "connectionString": "Server=localhost;Database=test;...",
  "schema": "dbo"
}

响应

[
  {
    "name": "Users",
    "schema": "dbo",
    "comment": "用户表"
  },
  {
    "name": "Products",
    "schema": "dbo",
    "comment": "产品表"
  }
]

3. 生成实体类

POST /smartdapper/api/generate
Content-Type: application/json

{
  "connectionString": "Server=localhost;Database=test;...",
  "schema": "dbo",
  "namespace": "MyApp.Entities",
  "outputDir": "Models",
  "tables": ["Users", "Products"],
  "overwrite": true,
  "enableSoftDelete": true
}

说明:

  • enableSoftDelete:是否生成软删(是否自动添加 [SoftDelete] 特性),默认 true。当为 false 时,即使存在 IsDeleted 等软删列,也不会生成 [SoftDelete],也不会触发 SmartDapper 包自动安装。

响应

{
  "tablesProcessed": 2,
  "filesWritten": 2,
  "outputFiles": [
    "D:\\MyProject\\Models\\User.cs",
    "D:\\MyProject\\Models\\Product.cs"
  ],
  "errors": []
}

4. 列出文件夹树

GET /smartdapper/api/folders

响应

{
  "name": "(解决方案根目录)",
  "path": ".",
  "children": [
    {
      "name": "src",
      "path": "src",
      "children": [...]
    },
    {
      "name": "test",
      "path": "test",
      "children": [...]
    }
  ]
}

⚠️ 注意事项

通用注意事项

  1. 输出路径安全:所有生成的文件路径都会被限制在 OutputRootDirectory 配置的目录下,防止任意文件写入攻击
  2. 文件覆盖:谨慎使用"覆盖已存在文件"选项,避免意外覆盖手动修改的代码
  3. 连接字符串安全:不要将包含敏感信息的连接字符串硬编码在代码中,建议使用配置文件或环境变量
  4. 命名冲突:注意数据库关键字和 C# 关键字的冲突,生成器不会自动处理关键字转义

SQL Server 特定注意事项

  1. 默认 Schema:如果不指定 Schema,默认使用 dbo
  2. 信任证书:开发环境建议在连接字符串中添加 TrustServerCertificate=True
  3. 加密连接:SQL Server 2022+ 默认需要加密连接
  4. NVARCHAR 类型:生成的实体会正确映射为 string(支持 Unicode)

MySQL 特定注意事项

  1. Schema 概念:MySQL 的 Database 相当于 SQL Server 的 Schema,因此通常留空 Schema 字段
  2. 端口号:建议显式指定 Port=3306,有助于数据库类型自动识别
  3. 字符集:建议使用 Charset=utf8mb4 支持完整的 Unicode 字符
  4. SSL 连接:开发环境可以设置 SslMode=None,生产环境建议启用 SSL
  5. 表名大小写:MySQL 在 Linux 上默认表名区分大小写,Windows 上不区分

性能建议

  1. 表数量:如果数据库包含大量表(100+ 张),建议使用搜索过滤功能
  2. 输出目录:避免选择包含大量文件的目录,可能影响文件夹树加载速度
  3. 连接超时:对于远程数据库,建议在连接字符串中设置合适的超时时间

🔧 故障排除

常见问题

1. 无法连接到数据库

现象:点击"加载表"后提示连接失败

解决方案

  • 检查连接字符串是否正确
  • 确认数据库服务正在运行
  • 检查防火墙设置
  • 对于 SQL Server,尝试添加 TrustServerCertificate=True
  • 对于 MySQL,尝试添加 SslMode=None

2. 找不到表

现象:加载表成功,但列表为空

解决方案

  • SQL Server:确认 Schema 设置是否正确(默认为 dbo
  • MySQL:尝试将 Schema 字段留空
  • 确认数据库用户有足够的权限读取表结构

3. 生成的文件路径错误

现象:提示"非法输出路径"

解决方案

  • 检查 OutputRootDirectory 配置是否正确
  • 确保输出目录在允许的根目录下
  • 使用相对路径而非绝对路径

4. 访问 UI 页面返回 401

现象:浏览器显示"Unauthorized"

解决方案

  • 检查是否配置了 AccessToken
  • 如果配置了令牌,需要在请求头中添加 X-SmartDapper-Token
  • 开发环境可以临时移除 AccessToken 配置

5. 自动安装 SmartDapper 包失败

现象:日志提示"未找到 .csproj 文件"或"安装失败"

解决方案

  • 确保输出目录位于项目目录内(包含 .csproj 文件)
  • 手动运行 dotnet add package SmartDapper
  • 检查 NuGet 源配置是否正确

🌟 最佳实践

  1. 解决方案级配置:将 OutputRootDirectory 设置为解决方案根目录,方便管理多个项目

    var solutionRoot = FindSolutionRoot(Directory.GetCurrentDirectory());
    options.OutputRootDirectory = solutionRoot ?? Directory.GetCurrentDirectory();
    
  2. 环境隔离:生产环境不要启用 SmartDapper.UI

    if (builder.Environment.IsDevelopment())
    {
        builder.Services.AddSmartDapperUi();
        // ...
    }
    
  3. 命名规范:使用有意义的命名空间,如 ProjectName.Domain.Entities

  4. 分层目录:为不同模块的实体创建独立目录

    Models/
    ├── Users/
    │   ├── User.cs
    │   └── UserRole.cs
    └── Products/
        ├── Product.cs
        └── Category.cs
    
  5. 版本控制:生成实体后,及时提交到版本控制系统

    git add Models/
    git commit -m "chore: generate entity classes from database"
    
  6. 增量生成:不要勾选"覆盖已存在文件",避免丢失手动添加的业务逻辑

  7. 文档注释:生成器会自动从数据库注释生成 XML 文档注释,确保数据库表和列有完善的注释

🤝 与 SmartDapper 集成

SmartDapper.UI 生成的实体类与 SmartDapper完美兼容:

using Dapper;
using SmartDapper.Extensions;

// 使用生成的实体类
var users = await connection.QueryAsync(
    "SELECT * FROM Users WHERE IsDeleted = 0");

// 软删除支持(自动过滤 IsDeleted = 1 的记录)
var activeUsers = await connection.GetAllAsync();

// Fluent API
var user = await connection.From()
    .Where(u => u.Username == "admin")
    .FirstOrDefaultAsync();

原文地址: https://www.cveoy.top/t/topic/qFZ5 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录