Dapper 本身不提供专门封装数据库函数(如 SQL Server 的
GETDATE()、MySQL 的
NOW()或自定义 UDF)的 API,但它完全支持在 SQL 语句中直接调用——只要你的数据库驱动(如 SqlClient、MySqlConnector、Npgsql)能执行该语句,Dapper 就能跑。
直接在 SQL 中写函数调用
这是最常用也最推荐的方式。UDF 和系统函数一样,属于 SQL 表达式的一部分,Dapper 只负责把 SQL 交给 ADO.NET 执行。
查询时嵌入函数:比如获取当前时间 + 计算字段var sql = "SELECT Id, Name, DATEDIFF(day, CreatedTime, GETDATE()) AS DaysAgo FROM Users WHERE Status = @status";
var users = connection.Query
var sql = "INSERT INTO Orders (OrderNo, Amount) VALUES (dbo.GenOrderNo(), @amount)";
connection.Execute(sql, new { amount = 99.9m });
注意 UDF 参数和返回值类型匹配
UDF 若带参数,必须确保传入值类型与数据库定义一致;若返回表值(TVF),要用
Query<t>()</t>;若返回标量,可用
QuerySingle<int>()</int>或
ExecuteScalar()。 标量 UDF 示例(SQL Server):
SELECT dbo.CalculateTax(@amount, 'CN')表值 UDF 示例:
SELECT * FROM dbo.GetUsersByDept(@deptId)→ 对应
Query<user>()</user>MySQL 自定义函数同理,如
SELECT my_udf_upper(name) FROM users
避免在 C# 端拼接函数名或参数名
不要用字符串拼接构造函数调用,尤其涉及 UDF 名称或 schema(如
dbo.fn_xxx)。这容易引发 SQL 注入或权限问题。所有动态部分应通过参数化(
@param)传递,函数名和结构应硬编码或从白名单读取。 ✅ 安全:
"SELECT * FROM dbo.GetUserById(@id)"❌ 危险:
$"SELECT * FROM {schema}.{udfName}(@id)"
特殊场景:需要捕获函数执行状态或错误
UDF 抛异常时,Dapper 会原样抛出 ADO.NET 异常(如
SqlException)。你可以用 try/catch 捕获,并检查
Number或
Message判断是否为 UDF 内部逻辑错误。 例如 SQL Server 中 UDF 抛出
RAISERROR,会触发
SqlException建议在 UDF 内部尽量用 RETURN 值代替异常,更利于 Dapper 统一处理
基本上就这些。Dapper 对函数的支持就是“透明”的——它不干预 SQL,只专注映射结果。你写得对,它就跑得通。
