当RowId为字符串类型时,如何使用或替代SQLiteBlob?
字符串类型RowId下的SQLite Blob写入方案
问题说明
SqliteBlob的构造函数仅支持SQLite原生的整数类型ROWID,而你传入的rowId是自定义的字符串主键列值,并非SQLite内置的ROWID,因此直接调用会报错,可通过以下两种方案解决:
方案一:使用参数化UPDATE语句写入Blob(推荐)
这是兼容性最好的方案,不依赖SqliteBlob的流特性,通过标准SQL命令实现,支持任意类型的主键:
public void WriteContent(Stream contentStream, string table, string rowId) { using var connection = this.executionContext.GetConnection(); connection.Open(); using var command = connection.CreateCommand(); // 替换YourStringPrimaryKeyColumn为你实际的字符串主键列名称 command.CommandText = $"UPDATE {table} SET {ColumnName} = @content WHERE YourStringPrimaryKeyColumn = @rowId"; command.Parameters.AddWithValue("@rowId", rowId); // 将输入Stream转为byte数组写入Blob列 using var memoryStream = new MemoryStream(); contentStream.CopyTo(memoryStream); command.Parameters.AddWithValue("@content", memoryStream.ToArray()); command.ExecuteNonQuery(); }
方案优势
- 支持字符串、UUID等非整数类型的主键
- 参数化查询避免SQL注入风险
- 适用于所有SQLite表(包括WITHOUT ROWID类型的表)
方案二:获取原生ROWID后使用SqliteBlob流写入
如果必须使用SqliteBlob的流操作,可先通过字符串主键查询出SQLite内置的整数ROWID,再基于该ROWID创建SqliteBlob:
public void WriteContent(Stream contentStream, string table, string rowId) { using var connection = this.executionContext.GetConnection(); connection.Open(); // 1. 查询对应字符串主键的原生整数ROWID using var getRowIdCmd = connection.CreateCommand(); getRowIdCmd.CommandText = $"SELECT ROWID FROM {table} WHERE YourStringPrimaryKeyColumn = @rowId"; getRowIdCmd.Parameters.AddWithValue("@rowId", rowId); var nativeRowId = getRowIdCmd.ExecuteScalar(); if (nativeRowId == DBNull.Value) { throw new InvalidOperationException($"未找到rowId为{rowId}的记录"); } // 2. 用原生ROWID创建SqliteBlob并写入流 using var writeStream = new SqliteBlob(connection, table, ColumnName, (long)nativeRowId); contentStream.CopyTo(writeStream); }
注意事项
- 仅适用于非WITHOUT ROWID类型的表(SQLite默认表都带ROWID)
- 需确保字符串主键列是唯一约束,避免返回多个ROWID
- 必须处理查询不到ROWID的异常情况
内容的提问来源于stack exchange,提问作者AnneTest123
相关产品推荐
相关产品推荐

