Microsoft.Data.Sqlite 重置 Size=0,字符串被截成空串
Microsoft.Data.Sqlite 10.0.13 中显式 Size=0 会把字符串和 blob 截成零长度。重置参数时使用明确的大小策略,区分零长度内容与 SQL NULL。
重用 SqliteParameter 时,先执行了一次 parameter.Size = 0,之后字符串或二进制数据变成空内容,命令却没有抛异常。这里的 0 不能当作“重新根据参数值推断大小”。
Microsoft.Data.Sqlite 10.0.13 的绑定器把显式设置的非负 Size 当成长度上限;0 会把非空字符串截成 "",把非空 byte[] 截成零长度 blob。这与没有设置 Size 不同:没有设置时,内部大小状态为空,值可按原长度绑定。
同样的公开属性值,不一定有同样的内部状态
Size 的 getter 可以根据现有字符串或字节数组返回长度;setter 则会记录调用方明确指定的上限。通用参数重置器若一律写回 0,就会让“尚未指定大小”变成“最多零个字符或字节”。
先检查参数构造、对象池重置和每次赋值的顺序,不只检查 SQL 列定义。尤其要找复用参数时统一设置 Size 的基础设施代码。把表列改成更大的 TEXT 或 BLOB,并不能撤销客户端绑定前的截断。
不需要截断时,使用明确的无限长哨兵
对于本来就允许发送完整值、且已完成应用输入校验的参数,可以在这个提供程序中显式使用 -1。下面是已有打开连接上的命令片段,SQL 只返回绑定值,便于在隔离环境确认传入内容:
using var command = connection.CreateCommand();
command.CommandText = "SELECT $value";
var parameter = command.Parameters.AddWithValue("$value", "TEST");
parameter.Size = -1;
var result = command.ExecuteScalar();
connection 是现有的 Microsoft.Data.Sqlite.SqliteConnection。在已核的 10.0.13 中,-1 不触发长度截断;字符串应完整返回为 TEST。也可重新创建一个不指定 Size 的参数,避免旧的显式限制继续留在复用对象上。
不要将这条规则直接推广到所有 ADO.NET 驱动。如果参数确实有业务长度限制,应保留相应校验与正的 Size,而不是批量改成 -1;特别是文本与 blob 的长度单位不同,限制应按实际数据类型审查。
也不能把空字符串、空 blob 和 DBNull.Value 混为一谈。它们在数据库里具有不同含义,修正重置逻辑时要分别保留。
新代码不会补回已经丢失的字段
这条故障会静默成功,判断修正不能只看受影响行数。在隔离副本上覆盖新参数、复用参数、显式 0、-1、正长度,以及空字符串、空 blob、SQL NULL,比较读回的完整内容或受控摘要。
截至 2026 年 10 月 23 日,已核正式 10.0.13 仍包含这条截断条件;不能把后续修改或问题关闭当作当前依赖已修复。部署前保存参数生成逻辑及原依赖,以便回退应用变更。
若已有记录被写成空内容,切换 Size 不会恢复它们。先依据可信输入记录或备份确认受影响范围,再审查数据修复;不要对所有空字段猜填同一个默认值,也不要直接回放可能重复写入的整个业务请求。


