Dapper怎么处理自定义SQL类型 Dapper UDT映射方法
发布时间 - 2026-01-03 00:00:00 点击率:次Dapper通过自定义ITypeHandler实现SQL Server UDT双向映射:SetValue序列化.NET实例为byte[]并设UdtTypeName,Parse反序列化byte[]为UDT实例;需注册处理器、确保UDT类符合序列化规范,并注意类型匹配与空值处理。
Dapper 本身不直接支持 SQL Server 的用户定义类型(UDT),但可以通过自定义 ITypeHandler 实现 UDT 的双向映射——即 .NET 类型 ↔ 数据库 UDT 值。
注册UDT类型处理器
SQL Server 的 UDT(如 Point、Geometry 或自定义 CLR 类型)需在数据库中已注册,并在 .NET 端有对应类(通常实现 INullable 和 IBinarySerialize)。Dapper 依靠 ITypeHandler 完成转换:
-
SetValue:把 .NET UDT 实例序列化为
SqlBytes或byte[],并设置parameter.UdtTypeName -
Parse:从数据库返回的
SqlBytes或object反序列化为 UDT 实例
示例(以自定义 UDT MyUdt 为例):
public class MyUdtHandler : SqlMapper.ITypeHandler
{
public void SetValue(IDbDataParameter parameter, object value)
{
parameter.Value = value == null ? DBNull.Value : ((MyUdt)value).ToBinary();
parameter.UdtTypeName = "dbo.MyUdt"; // 必须与数据库中注册名一致
}
public object Parse(Type destinationType, object value)
{
if (value == null || value == DBNull.Value) return null;
var bytes = (byte[])value;
return MyUdt.FromBinary(bytes);
}
}
注册方式:
SqlMapper.AddTypeHandler(typeof(MyUdt), new MyUdtHandler());
确保UDT类符合SQL Server要求
.NET 端 UDT 类必须满足 SQL Server 的序列化规范,典型结构包括:
- 标记
[Serializable]和[SqlUserDefinedType(Format.Native)](或Format.UserDefined+IBinarySerialize实现) - 提供静态
Parse()和实例ToBinary()方法 - 无参构造函数(用于反序列化)
若使用 Format.UserDefined,必须完整实现 IBinarySerialize.Read() 和 Write()。
配合Dapper.Contrib或QueryMultiple使用注意事项
UDT 字段在查询中默认无法自动映射到实体属性,除非:
- 该属性类型与注册的
ITypeHandler类型完全匹配(含可空性,如MyUdt?需额外注册) - 避免在
Query中混用未映射字段;建议显式 SELECT 所需列,或用匿名类型过渡() - 插入/更新时,确保参数对象中 UDT 属性值非 null 或已正确处理 null 场景(如设为
DBNull.Value)
替代方案:用内置类型绕过UDT(适用简单场景)
如果 UDT 仅用于封装简单数据(如坐标字符串、编码后的结构),更轻量的做法是:
- 数据库层仍用 UDT 列,但 Dapper 层统一按
string或byte[]处理 - 注册
string→MyUdt的转换器(在业务逻辑中解析),
而非让 Dapper 直接持有 UDT 类型 - 这样可规避 UDT 部署依赖,也便于跨数据库兼容
基本上就这些。关键不是“能不能”,而是“谁负责序列化”——Dapper 把控制权交给你,你只需守住 SetValue 和 Parse 这两个入口。
# 处理器
# 编码
# app
# .net
# sql
# String
# Object
# NULL
# 封装
# 构造函数
# select
# format
# 字符串
# 对象
# 数据库
# 自定义
# 序列化
# 数据库中
# 只需
# 设为
# 并在
# 所需
# 这两个
# 可以通过
# 为例
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
网站图片在线制作软件,怎么在图片上做链接?
JavaScript常见的五种数组去重的方式
Win10如何卸载预装Edge扩展_Win10卸载Edge扩展教程【方法】
如何在企业微信快速生成手机电脑官网?
Laravel表单请求验证类怎么用_Laravel Form Request分离验证逻辑教程
如何快速搭建自助建站会员专属系统?
香港网站服务器数量如何影响SEO优化效果?
Laravel项目结构怎么组织_大型Laravel应用的最佳目录结构实践
网站广告牌制作方法,街上的广告牌,横幅,用PS还是其他软件做的?
教你用AI将一段旋律扩展成一首完整的曲子
Laravel事件监听器怎么写_Laravel Event和Listener使用教程
jimdo怎样用html5做选项卡_jimdo选项卡html5实现与切换效果【指南】
EditPlus 正则表达式 实战(3)
laravel怎么为应用开启和关闭维护模式_laravel应用维护模式开启与关闭方法
Angular 表单中正确绑定输入值以确保提交与验证正常工作
晋江文学城电脑版官网 晋江文学城网页版直接进入
如何用PHP快速搭建CMS系统?
Laravel如何安装使用Debugbar工具栏_Laravel性能调试与SQL监控插件【步骤】
使用PHP下载CSS文件中的所有图片【几行代码即可实现】
DeepSeek是免费使用的吗 DeepSeek收费模式与Pro版本功能详解
Laravel如何创建自定义Artisan命令?(代码示例)
如何构建满足综合性能需求的优质建站方案?
如何在阿里云完成域名注册与建站?
如何快速生成凡客建站的专业级图册?
Laravel如何使用Spatie Media Library_Laravel图片上传管理与缩略图生成【步骤】
HTML 中如何正确使用模板变量为元素的 name 属性赋值
利用 Google AI 进行 YouTube 视频 SEO 描述优化
Laravel如何处理CORS跨域问题_Laravel项目CORS配置与解决方案
Laravel如何处理文件上传_Laravel Storage门面实现文件存储与管理
如何快速生成高效建站系统源代码?
香港服务器部署网站为何提示未备案?
如何安全更换建站之星模板并保留数据?
大连网站制作费用,大连新青年网站,五年四班里的视频怎样下载啊?
如何为不同团队 ID 动态生成多个非值班状态按钮
哪家制作企业网站好,开办像阿里巴巴那样的网络公司和网站要怎么做?
如何在IIS中新建站点并配置端口与IP地址?
如何挑选最适合建站的高性能VPS主机?
手机网站制作平台,手机靓号代理商怎么制作属于自己的手机靓号网站?
Internet Explorer官网直接进入 IE浏览器在线体验版网址
如何自定义建站之星模板颜色并下载新样式?
google浏览器怎么清理缓存_谷歌浏览器清除缓存加速详细步骤
Laravel Asset编译怎么配置_Laravel Vite前端构建工具使用
Laravel策略(Policy)如何控制权限_Laravel Gates与Policies实现用户授权
HTML5空格和nbsp有啥关系_nbsp的作用及使用场景【说明】
奇安信“盘古石”团队突破 iOS 26.1 提权
为什么要用作用域操作符_php中访问类常量与静态属性的优势【解答】
如何在VPS电脑上快速搭建网站?
想要更高端的建设网站,这些原则一定要坚持!
如何选择可靠的免备案建站服务器?
公司网站制作价格怎么算,公司办个官网需要多少钱?


而非让 Dapper 直接持有 UDT 类型