1

Due to reasons beyond my control, I am creating a .NET 2.0 assembly in which I load a SQLite database and retrieve some binary data from it. Specifically, PDF documents.

The documentation for System.Data.SQLite.SQLiteDataReader.GetBlob(int i, bool ReadOnly) says: (emphasis mine)

Retrieves the column as a System.Data.SQLite.SQLiteBlob object. This will not work for tables that were created WITHOUT ROWID -OR- if the query does not include the "rowid" column or one of its aliases -OR- if the System.Data.SQLiteDataReader was not created with the System.Data.CommandBehavior.KeyInfo flag.

Here is my SQLiteCommand:

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

I have instantiated my SQLiteDataReader like so:

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

I call the GetBlob(int i, bool ReadOnly) function as follows:

currentCustomerPdf = currentCustomerReader.GetBlob(1, true);

And I'm greeted with this:

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)
...

Am I doing something wrong? Am I missing a step? Do I need to file a bug? Is it an issue with .NET 2.0 that has been resolved in newer versions?

4
  • Do you really need random access to the blob? Can't you just read it as a byte array? Commented Dec 8, 2016 at 14:49
  • I'm researching how to do that now. I'm just not sure why this is happening -- I'd really like to know -- and the code for the Blob object is simpler and takes fewer lines. Commented Dec 8, 2016 at 15:04
  • That SQLiteBlob object obviously uses incremental blob I/O. But I don't see why it doesn't work in this case. Commented Dec 8, 2016 at 15:08
  • Thanks. I don't understand why it isn't working either. Smells like a bug to me. Commented Dec 8, 2016 at 15:11

2 Answers 2

2

To make this code work, either:

  1. Remove the System.Data.CommandBehavior.SequentialAccess flag and select at least the rowid and blob field.

  2. Just call ExecuteReader with parameter CommandBehavior.KeyInfo (no need for rowid in the query).

Sign up to request clarification or add additional context in comments.

Comments

0

though keyinfo works, but it does not solve the increment blob I/O of large blob objects due to the fact of executereader method's large memory consumption(as much as equal to the blob size). One way to avoid the huge memory usage is to get the rowid in a separate query and overload the sqliteblob.create method and pass the rowid directly. So basically keyinfo is not all needed here if you can overload the sqliteblob.create method.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.