Dapper的splitOn参数支持多个吗 Dapper多重splitOn用法

8次阅读

Dapper的splitOn支持用英文逗号分隔多个列名,用于多级嵌套映射;如查询返回OrderId,OrderNo,CustomerId,CustomerName,AddressId,Street,需写splitOn:”CustomerId,AddressId”以正确分割Order、Customer、Address三个对象

Dapper的splitOn参数支持多个吗 Dapper多重splitOn用法

Dapper 的 splitOn 参数支持多个列名,用英文逗号分隔即可,比如 splitOn: "OrderId,ProductId"。这不是“多次 splitOn”,而是一次指定多个分割点,用于多级嵌套映射(如一查三:Order → Customer → Address)或一对多场景中区分不同实体的起始字段。

什么时候需要多个 splitOn

sql 查询返回三张及以上表的扁平化结果(例如 JOIN 了 Order、Customer、Address),且各实体主键列名不统一(比如不是都叫 Id)时,Dapper 需要明确知道每个新对象从哪一列开始。这时就靠多个列名告诉它:“这里切一刀,开始映射下一个对象”。

  • 第一个对象(如 Order)取 splitOn 之前的所有列
  • 第二个对象(如 Customer)从第一个 splitOn 列(如 CustomerId)开始,到下一个 splitOn 列前为止
  • 第三个对象(如 Address)从第二个 splitOn 列(如 AddressId)开始,取剩余所有列

正确写法示例

假设查询返回:OrderId, OrderNo, CustomerId, CustomerName, AddressId, Street

你想映射为 Order → Customer → Address

var result = conn.Query(     sql,     (order, customer, address) =>     {         order.Customer = customer;         customer.Address = address;         return order;     },     splitOn: "CustomerId,AddressId" // 关键:两个分割点 );

常见误区提醒

  • 不要重复写多个 splitOn 参数:Dapper 只接受一个 splitOn: 参数,值是字符串,不是数组或多个键值对
  • 顺序必须和泛型参数顺序一致:泛型是 ,那 splitOn 中第一个列对应 T2 起始,第二个列对应 T3 起始
  • 列名必须真实存在于 select 结果中,且大小写需匹配(取决于数据库配置,建议显式别名)
  • 如果某关联记录为空(如 Customer 为 NULL),Dapper 仍能正常映射,但你要在委托函数里判空,避免 NullReferenceException

一对多场景下不直接靠 splitOn 解决

splitOn 本身只处理“一对一”或“线性嵌套”,不能自动展开集合(如一个 Order 对应多个 OrderItem)。要做一对多,得配合 Dictionary 手动归组,或者改用 QueryMultiple 分步查——这时候 splitOn 就只用一次,甚至不用。

基本上就这些。

text=ZqhQzanResources