2

I am trying to access a column of Blob's in an SQLite DB which will eventually be pointers to a record on a file or in memory. I'm trying to use the .GetBytes method in SQLite to get an array of bytes that will represent my data. I keep getting an InvalidCastException while using this method. Everything seems to be in place and the program compiles just fine, but during runtime this exception keeps getting thrown. I've looked around for answers and everything seems to agree with the code I have so I am at a loss here, and unfortunately I can't find any good documentation for SQLite in C#. Code is as follows

  public byte[] Output()
    {
        byte[] temp = null;
        int col = Columns + 1;
        if(read.Read())
        {
            read.GetBytes(col, 0, temp, 0, 2048); //exception is thrown here
        }
        return temp;
    }

I've been able to read other columns in the DB that are ints and texts, but for some reason can't seem to get the blobs right.

EDIT: new info, Here is the stack trace from the exception:

     StackTrace:
   at System.Data.SQLite.SQLiteDataReader.VerifyType(Int32 i, DbType typ)
   at System.Data.SQLite.SQLiteDataReader.GetBytes(Int32 i, Int64 fieldOffset, Byte[] buffer, Int32 bufferoffset, Int32 length)
   at SQLiteSort.Sort.Output() in C:\Users\cjones\Documents\Visual Studio 2010\Projects\ConsoleApplication1\ConsoleApplication1\Sort.cs:line 192
   at SQLiteSort.Sort.Main(String[] args) in C:\Users\cjones\Documents\Visual Studio 2010\Projects\ConsoleApplication1\ConsoleApplication1\Sort.cs:line 72
   at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
   at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
   at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
   at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.ThreadHelper.ThreadStart()

InnerException:

The exception seems to be thrown by SQLiteDataReader.VerifyType(), this is looking at the column being used for a DbType.Binary type and throws an exception if the column is not a DbType.Binary, DbType.String, or DbType.Guid. I've checked the table over and over and it still shows the column type as a blob.

4
  • What is the message in the exception? For instance, Unable to cast object of type 'System.DBNull' to type 'System.Byte[]'.? Commented May 24, 2012 at 22:52
  • System.InvalidCastException was unhandled Message=Specified cast is not valid. Source=System.Data.SQLite Commented May 24, 2012 at 22:53
  • 1
    Okay, better question, if you add if (read.IsDBNull(col)) return null; before the read, does it solve the problem? Commented May 24, 2012 at 22:59
  • Nope, it does not. I'm able to look at the read object in VS and can see that the column is populated with bytes. Commented May 24, 2012 at 23:02

3 Answers 3

1

The fact that it throws an InvalidCastException certainly seems wrong, but your code is broken - temp will be null, which surely it shouldn't be. You're not providing anywhere for the data to be read to.

You're also not taking note of the return value of GetBytes, which I'd expect you to...

EDIT: Just to check... you are trying to read from an appropriate column, right? InvalidCastException would be somewhat appropriate if you were trying to call GetBytes on (say) an integer column.

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

7 Comments

I've tried setting temp to a new object byte[] temp = new byte[2048] , but still get the same exception. I realize GetBytes returns a value but I have no use for it that I can think of.
@ChrisJones: Why on earth would you not want to know how much data has been read? And which line is throwing the exception? If you could produce a short but complete program demonstrating the problem, that would really help.
Yes I am trying to read the correct column, I just checked to make sure that wasn't the problem.
It seemed fishy to me that the SQLite driver itself would throw a cast exception (particularly for reading binary data), given that it doesn't really enforce types to begin with. So, I poked my head into the source code, and discovered that ReadBytes will explicitly throw an exception if the affinity of the column is not "BLOB", (otherwise known as none). Something is definitely wrong either with the table definition, or the column being referenced.
@mootinator - the table definition is definitely "BLOB" and I'm trying to access that column. I can access it by using .ToString() and it outputs System.Byte[] so I know most definitely that it is a byte[] and it is accessible, just confused as to why it won't let me access it as a byte[]. Is there maybe something wrong with the .GetBytes() method?
|
1

I found out that with BLOB database type in Sqlite, the correspondent type in C# for the reader is char[].

The following code worked for me:

char[] buff = null;
long read = reader.GetChars(col, 0, buff, 0, int.MaxValue);
buff = new char[read];
reader.GetChars(col, 0, buff, 0, buff.Length);

Comments

0

Well I finally fixed the problem by using parameter's and setting my Blob to DbType.Binary. Not sure why this is so different from what I was doing before but everything is working as it should now.

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.