agilelabs-fx-docs main topics/data-access-dapper.md

数据访问(Dapper,推荐)

本页是 AgileLabs Framework 当前推荐的数据访问主题页。新项目和新增模块默认走 Dapper / SQL 主路径;如果你正在维护遗留 EF Core,请改看 数据访问(EF Core,过期)EF Core 迁移到 Dapper

适用场景

  • 基于 SqlBaseRepository 的 SQL / Dapper 数据访问。
  • 需要显式控制 SQL、事务、分页和并发的项目。
  • 希望让 AI 生成的数据访问代码更容易被审查、修正和验收的团队。

必须遵守

  • 新项目默认走 Dapper / SQL 路线,不再把 EF Core 作为默认数据访问方案。
  • Repository 生命周期为 Scoped
  • 数据访问必须通过业务 Repository 暴露,不把 SQL、连接和事务控制泄漏到 Controller。
  • 审计字段、租户身份、操作者身份等上下文相关逻辑必须运行在有效 WorkContext 内。
  • 写入逻辑要显式表达更新条件、并发字段和影响行数校验,不依赖 ORM 隐式提交。

推荐做法

  • 默认新建 SqlBaseRepository 派生类承接查询、分页、显式事务和写入。
  • 业务 Repository 表达业务语义,不把 Controller 直接暴露给底层访问细节。
  • 并发控制、审计字段回填、字段映射和返回 DTO 在 Repository 或其相邻的应用层内显式完成。
  • 查询、分页、批量和事务统一收敛在业务 Repository 内,不把 SQL 字符串散落到控制器和服务层。

源码入口

  • AgileLabs.Storage.PostgreSql/SqlBaseRepository.cs:复杂 SQL / Dapper 访问基类。
  • AgileLabs.Storage.PostgreSql:Dapper / SQL 主路径所在类库。

为什么当前推荐 Dapper / SQL

Dapper 路线的核心特点是行为显式、SQL 可见、事务边界清晰,AI 生成结果也更容易被人审查和修正。当前默认建议是:

  • 查询、分页、批量和事务直接放在 SqlBaseRepository 派生类中。
  • 写入逻辑显式表达更新条件、并发字段和影响行数检查。
  • 审计字段、租户信息、操作者信息通过 WorkContext 显式带入。
  • 不依赖 ORM 的隐式跟踪、隐式提交和导航属性级联行为。

Dapper 主路径分层关系

flowchart TD
    Controller[Controller / AppService]
    Repo[业务 Repository]
    Sql[SqlBaseRepository]
    Pg[(PostgreSQL)]

    Controller --> Repo
    Repo --> Sql
    Sql --> Pg

什么时候选什么

场景 推荐方式 原因
新项目的标准读写 SqlBaseRepository 派生类 SQL 显式,可审查,可控
复杂列表、分页、多表查询 SqlBaseRepository SQL 表达更直接,分页能力更清晰
批量写入、显式事务 SqlBaseRepository 更适合控制事务和批量执行
需要 ts 并发控制 SqlBaseRepository + 显式 where 条件 冲突边界清晰
存量 EF Core 模块维护 不走本页主路径 改看 EF Core 过期页与迁移页

Dapper 写入链路

请求内的推荐写入链路应该保持显式:

sequenceDiagram
    participant Action as Controller / Service
    participant Repo as Repository
    participant Sql as SqlBaseRepository
    participant Db as PostgreSQL

    Action->>Repo: 调用增删改业务
    Repo->>Sql: ExecuteNoQueryAsync / TransScopeAsync
    Sql->>Db: 执行显式 SQL
    Db-->>Sql: 返回影响行数 / 查询结果
    Sql-->>Repo: 显式结果
    Repo-->>Action: DTO / 业务结果

这条链路的重点是:

  1. SQL、事务和并发检查都在 Repository 内显式表达。
  2. 影响行数、版本字段和失败分支不依赖隐式 SaveChanges 行为。
  3. 审计字段可以在参数组装时显式回填,或通过项目基类统一填充。

审计字段与 WorkContext

推荐主路径下,审计字段、租户身份和操作者身份仍依赖 WorkContext

  • 在 HTTP 请求里通常天然成立。
  • 在后台任务里必须先建 WorkContext,再做数据保存。
  • 如果你绕过 WorkContext 直接写库,最轻是审计字段缺失,最重会出现身份、租户或时间语义错误。

推荐的新项目注册示例:

services.AddScoped<OrderRepository>();
services.AddScoped<DapperBaseRepository>();

如果你在维护遗留 EF Core

如果当前项目已经依赖 AgileLabDbContextCrudRepository 或 EF Core migration,不要继续把它当作主路径扩展。请改看 数据访问(EF Core,过期)EF Core 迁移到 Dapper

常见坑

  • 新模块继续新增 DbContextCrudRepository
  • 在同一业务里同时混用 Dapper 写入和 EF Core 写入,却没有清晰边界。
  • 在 Controller 里直接拼连接和事务。
  • 把审计字段、并发字段和失败分支继续交给隐式行为兜底。

示例与落地对照

  • gmandarin-backend:大量显式业务仓储。
  • woscm:适合重点看项目级 Dapper 基类、ts 并发控制和项目标准层封装。

相关页面