Dapper怎么处理数据库函数 Dapper调用UDF用户定义函数

来源:这里教程网 时间:2026-02-21 17:40:06 作者:

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(sql, new { status = 1 });

插入/更新时调用 UDF:比如用自定义函数生成编码

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,只专注映射结果。你写得对,它就跑得通。

相关推荐