SQL Server搭配Dapper传参不生效,求正确的参数赋值方法
问题根源
参数不生效的核心原因是Dapper默认将.NET字符串类型映射为SQL Server的nvarchar类型,与你数据库中的char定长非Unicode字段类型不匹配:做等值查询时SQL Server会自动将char字段隐式转换为nvarchar类型再比较,不仅会导致字段索引失效,还可能因为字符集、尾部空格填充规则差异直接匹配不到结果。你直接拼接字符串的写法相当于传入了char类型的常量,避开了类型不匹配问题,但存在SQL注入、执行计划无法复用的缺陷,不推荐使用。
正确的参数赋值方式
方式1:用DynamicParameters显式指定参数类型(适合临时查询场景)
直接通过DynamicParameters显式声明参数的类型、长度,和数据库字段完全匹配即可:
using Dapper; using System.Data; // 构造参数 var parameters = new DynamicParameters(); // DbType.AnsiStringFixedLength 对应SQL Server非Unicode定长字符类型char parameters.Add("@FooNo", "00007829", DbType.AnsiStringFixedLength, size: 8); parameters.Add("@yyyyMMdd", "20210812", DbType.AnsiStringFixedLength, size: 8); parameters.Add("@Point", "001A", DbType.AnsiStringFixedLength, size: 4); // 执行查询 var result = this.OpenedConn.Query(sql1, parameters).ToList();
如果你的数据库字段是Unicode定长的nchar类型,将DbType替换为StringFixedLength即可。
方式2:强类型参数类加特性标记(适合复用查询场景)
如果该查询会多次复用,可以定义专用的参数类,通过特性标记参数属性的类型规则,调用时和原来的匿名类写法几乎一致:
using Dapper; using System.Data; public class FooQueryParams { [DbType(DbType.AnsiStringFixedLength), Size(8)] public string FooNo { get; set; } [DbType(DbType.AnsiStringFixedLength), Size(8)] public string yyyyMMdd { get; set; } [DbType(DbType.AnsiStringFixedLength), Size(4)] public string Point { get; set; } } // 调用代码 var parameters1 = new FooQueryParams { FooNo = "00007829", yyyyMMdd = "20210812", Point = "001A" }; var result = this.OpenedConn.Query(sql1, parameters1).ToList();
内容的提问来源于stack exchange,提问作者takemori_kondo
相关产品推荐
相关产品推荐

