使用System.Data.SQLite.SQLIteDataReader.GetBlob

时间:2016-12-08 14:27:28

标签: c# sqlite blob .net-2.0 system.data.sqlite

由于我无法控制的原因,我正在创建一个.NET 2.0程序集,在其中加载SQLite数据库并从中检索一些二进制数据。具体来说,是PDF文档。

System.Data.SQLite.SQLiteDataReader.GetBlob(int i,bool ReadOnly)的文档说:(强调我的)

  

将列检索为System.Data.SQLite.SQLiteBlob对象。 如果查询不包含“rowid”列或其中一个别名-OR-,如果未使用System创建System.Data.SQLiteDataReader,则这对于使用ROWID -OR-创建的表不起作用。 Data.CommandBehavior.KeyInfo标志。

这是我的SQLiteCommand:

using (SQLiteCommand getBooklet = new SQLiteCommand($"SELECT \"rowid\", File_Name FROM Booklets WHERE Id = {int.Parse(key)}", dbConnection))

我像我这样实例化了我的SQLiteDataReader:

using (SQLiteDataReader currentCustomerReader = getBooklet.ExecuteReader(System.Data.CommandBehavior.KeyInfo & System.Data.CommandBehavior.SequentialAccess))

我调用GetBlob(int i,bool ReadOnly)函数如下:

currentCustomerPdf = currentCustomerReader.GetBlob(1, true);

我受到了欢迎:

System.InvalidOperationException: No RowId is available
    at System.Data.SQLite.SQLiteBlob.Create(SQLiteDataReader dataReader, Int32 i, Boolean readOnly)
    at System.Data.SQLite.SQLiteDataReader.GetBlob(Int32 i, Boolean readOnly)
...

我做错了吗?我错过了一步吗?我需要提交错误吗?是否已在较新版本中解决了.NET 2.0的问题?

2 个答案:

答案 0 :(得分:1)

要使此代码生效,请删除System.Data.CommandBehavior.SequentialAccess标志并至少选择rowid和blob字段。

答案 1 :(得分:0)

尽管keyinfo有效,但它并没有解决大blob对象的增量blob I / O,因为executereader方法的内存消耗很大(与blob大小相同)。避免大量内存使用的一种方法是在单独的查询中获取rowid并重载sqliteblob.create方法并直接传递rowid。因此,如果你可以重载sqliteblob.create方法,那么基本上不需要keyinfo。