5

我在 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;
        }
        ...
    }
}

为什么将长度与4000进行比较?

4

1 回答 1

9

查询计划缓存。

以下查询是分开且独立的:

select @foo

select @foo

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

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

请注意,所有这些只有在您没有Length明确设置时才会发生;如果您想对此进行更多控制,只需设置.Length为您想要的。关键属性是:

  • IsAnsi- 在 unicode/not 之间切换 - nin[n][var]char(len)
  • IsFixedLength- 在固定/可变长度之间切换 -var[n][var]char(len)
  • Length-len[n][var]char(len)
  • Value- 实际内容
于 2013-07-02T07:08:35.747 回答