我在小巧玲珑中找到了这些代码:
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进行比较吗?
谢谢。答案 0 :(得分:8)
查询计划缓存。
以下查询是独立且独立的:
select @foo
和
select @foo
如果您感到困惑,那是因为我没有显示的位是参数声明 - 在第一个中它是nvarchar(12)
而在第二个中它是{{ 1}}。代码尝试避免的代码是单个查询,执行两次 - 例如一次使用nvarchar(20)
(5个字符),一次使用hello
(6个字符)执行两次单独查询查询计划;这比允许两者共享计划的效率低得多,而且这种选择负面影响事物的次数消失小。
通过将长度标准化为某个任意值,它允许大多数常见值使用相同的查询计划缓存。 world!
相当随意(嗯,实际上是因为4000
是开始进入nvarchar(4000)
区域之前的最大尺寸),因此max
也可以200
或者你想要的任何东西。代码的工作原理是大部分时间值都相当短,所以如果是更大的值,它们将是例外而不是规则。
请注意,只有在未明确设置Length
的情况下才会发生所有这些情况。如果您想要更多地控制它,只需将.Length
设置为您想要的。关键属性是:
IsAnsi
- 在unicode / not之间切换 - n
中的[n][var]char(len)
IsFixedLength
- 在固定/可变长度之间切换 - var
中的[n][var]char(len)
Length
- len
[n][var]char(len)
Value
- 实际内容