Dapper不直接支持执行SQL脚本文件,需先读取文件内容为字符串,再按GO分隔符分割语句,最后逐条调用Execute在事务中执行。

Dapper 本身不直接支持执行 SQL 脚本文件(如 .sql 文件),它只是一个轻量级的 ORM,只负责将 SQL 字符串映射到对象或执行单条/批量命令。要运行一个完整的 SQL 脚本文件(比如包含多条语句、GO 分隔、注释、条件逻辑等),你需要先读取文件内容,再手动解析并分段执行。
读取 .sql 文件内容
最基础的一步是把 SQL 脚本加载为字符串:
- 使用
File.ReadAllText("script.sql")或异步版本File.ReadAllTextAsync - 确保文件编码正确(推荐 UTF-8,尤其含中文或特殊字符时)
- 路径建议用绝对路径或基于
AppContext.BaseDirectory构建相对路径
分割多条 SQL 语句(处理 GO 分隔符)
SQL Server 的 GO 不是 T-SQL 语句,而是客户端工具(如 SSMS)识别的批处理分隔符。Dapper 不认识 GO,必须手动切分:
- 按行拆分,跳过空行和注释行(
--或/*...*/需简单过滤) - 遇到独立一行的
GO(忽略前后空格)就作为语句边界 - 推荐用现成小工具,比如 SqlCeToolbox 的
SqlScript类,或轻量解析器如Microsoft.Data.SqlClient.Scripts(.NET 6+) - 简单场景下可用正则:
Regex.Split(content, @"^\s*GO\s*$", RegexOptions.IgnoreCase | RegexOptions.Multiline)
用 Dapper 执行每条语句
拿到语句数组后,逐条传给 Dapper 执行(注意:不能用 Query/QuerySingle,要用 Execute):
-
connection.Execute(sqlStatement, transaction: trans)—— 推荐在事务中执行,保证原子性 - 跳过空字符串和纯注释语句(避免抛异常)
- 对 CREATE/ALTER/DROP 等 DDL 语句,SQL Server 允许在同一连接中执行,无需特别处理
- 如果脚本含临时表或会话级设置(如
SET ANSI_NULLS ON),需确保都在同一连接+同一事务中执行
完整示例(简化版)
以下是一个最小可行示例(无复杂注释处理,仅支持 GO 分割):
var script = File.ReadAllText("init.sql");
var statements = Regex.Split(script, @"^\s*GO\s*$", RegexOptions.IgnoreCase | RegexOptions.Multiline);
using var conn = new SqlConnection(connStr);
conn.Open();
using var trans = conn.BeginTransaction();
try
{
foreach (var stmt in statements.Select(s => s.Trim()).Where(s => !string.IsNullOrEmpty(s)))
{
conn.Execute(stmt, transaction: trans);
}
trans.Commit();
}
catch
{
trans.Rollback();
throw;
}
基本上就这些。Dapper 不做脚本解析,但配合基础 IO 和简单文本处理,完全能胜任 SQL 脚本部署任务。关键点是:读得准、切得对、执行稳(加事务)、错得清(有回滚)。










