I have a database schema that I do not control (it's a sqlite3 file exported from a desktop application that I need to interoperate with), that contains UUIDs for some of the columns. I'm using sqlite-net-pcl
in a Xamarin.Forms app, and I cannot work out how to successfully read these columns. Here's what I've tried:
uuid
for the relevant column, and using select count(distinct uuidcolumn) from mytable;
I've confirmed that there are values for each row. (The column is nullable which is relevant for the code snippet below but in practice all the rows have non-null values)namespace brahms.Model
{
[Table("mytable")]
public class MyTable
{
[Column("uuidcolumn")]
public Guid UUIDColumn { get; }
[PrimaryKey, AutoIncrement, NotNull]
[Column("recordid")]
public int RecordID { get; set; }
}
}
database.Query<MyTable>()
queries, UUIDColumn
is always equal to Guid.Empty
.Byte[]
; it's always null
.string
; it's always null
.UInt16[]
type (the GUID might be stored as a blob of 16-bit words, so I tried that type too)How can I read the values in uuid
-typed columns using sqlite-net-pcl
?
I gave up on using the ORM features in sqlite-net-pcl
and used this query:
db.executeScalar<byte[]>('select hex(uuidcolumn) from mytable where recordid=1');
What I get back is 72 bytes, which appear to represent the 36 ASCII characters in a string representation of a Guid (every so often one of the characters is 2D
, which is -
in the ASCII set). So I think that the backing store is a blob but one that's storing the text representation of the Guid, which is weird, but I'll be able to reconstruct the Guid from here.
Using this answer and getting that blob as a string, I ended up with this implementation:
public Guid GetUUIDColumn()
{
string dbRep = _database.ExecuteScalar<string>("select hex(uuidcolumn) from mytable where recordid = ?", RecordID);
if (dbRep == null || dbRep == string.Empty) return Guid.Empty;
var bytes = new byte[dbRep.Length / 2];
// each pair of bytes represents the ASCII code (in hexadecimal) for a character in the string representation of a Guid.
for (var i = 0; i < bytes.Length; i++)
{
bytes[i] = Convert.ToByte(dbRep.Substring(i * 2, 2), 16);
}
string asString = Encoding.ASCII.GetString(bytes);
return new Guid(asString);
}