dapper中字符串到varchar的处理程序映射

dapper中字符串到varchar的处理程序映射,dapper,Dapper,我在Dapper中找到以下代码: sealed partial class DbString : Dapper.SqlMapper.ICustomQueryParameter { ... public void AddParameter(IDbCommand command, string name) { ... var param = command.CreateParameter(); param.ParameterN

我在Dapper中找到以下代码:

sealed partial class DbString : Dapper.SqlMapper.ICustomQueryParameter
{
    ...

    public void AddParameter(IDbCommand command, string name)
    {
        ...
        var param = command.CreateParameter();
        param.ParameterName = name;
        param.Value = (object)Value ?? DBNull.Value;
        if (Length == -1 && Value != null && Value.Length <= 4000)
        {
            param.Size = 4000;
        }
        else
        {
            param.Size = Length;
        }
        ...
    }
}
密封部分类DbString:Dapper.SqlMapper.ICustomQueryParameter
{
...
public void AddParameter(IDbCommand,字符串名)
{
...
var param=command.CreateParameter();
param.ParameterName=名称;
参数值=(对象)值??DBNull.Value;
if(Length==-1&&Value!=null&&Value.Length查询计划缓存

以下查询是独立的:

select @foo

如果您感到困惑,那是因为我没有显示的位是参数声明-在第一个中是
nvarchar(12)
,在第二个中是
nvarchar(20)
。代码试图避免的是一个单独的查询,执行两次-例如一次使用
hello
(5个字符)有一次,使用
world!
(6个字符)有两个单独的查询计划;这比允许两者共享一个计划效率要低得多,而且这种选择会对事情产生负面影响的情况非常少

通过将长度标准化为某个任意值,它允许最常见的值使用相同的查询计划缓存。
4000
是相当任意的(实际上,选择它是因为
nvarchar(4000)
是它开始进入
max
区域之前的最大大小),也可以是
200
,或者任何你想要的。代码的工作基础是大多数时间值都相当短,因此如果有较大的值,它们将是例外而不是规则

请注意,只有在未明确设置
长度
的情况下,才会发生所有这些情况;如果希望对此进行更多控制,只需将
.Length
设置为所需的值即可。关键属性包括:

  • IsAnsi
    -在unicode/not之间切换-在
    [n][var]char(len)
  • IsFixedLength
    -在固定/可变长度之间切换-在
    [n][var]char(len)
  • Length
    -在
    [n][var]char(len)
  • -实际内容

嗯,似乎我的理解完全错误。但是,根据中的说明:
…对于大于4000个字符的字符串,显式设置SqlDbType。
和您的解释,没有任何
显式设置`在这里,为什么它仍然有效?@pinopino dapper总是显式设置类型;在您的示例中,它在
..
-实际行是
parameter.DbType=this.IsAnsi?(this.IsFixedLength?DbType.AnsiStringFixedLength:DbType.AnsiString):(this.IsFixedLength?DbType.StringFixedLength:DbType.String);
我们使用
DbType
而不是
SqlDbType
,因为dapper没有绑定到SQL Server(它适用于任何ADO.NET提供程序)-但结果是一样的;这传达了相同的信息。对不起,事实上这完全是另一个问题,我发布了。对于这一个问题,谢谢你,马克,你的解释对我帮助很大!只是要清楚一点,IsAnsi对于varchar应该为true,对于nvarchar应该为false。IsFixed对于[n]应该为true[n]varchar的char和false。
select @foo