如何使用 Xamarin Forms 中的 sqlite-net-pcl 从 sqlite3 db 的列中读取`uuid`

问题描述

我有一个我无法控制的数据库架构(它是从我需要与之交互的桌面应用程序导出的 sqlite3 文件),其中包含某些列的 UUID。我在 Xamarin.Forms 应用程序中使用 sqlite-net-pcl,但我不知道如何成功读取这些列。这是我尝试过的:

  • 使用 sqlite3 命令行,我已确认架构具有相关列的类型 uuid,并使用 select count(distinct uuidcolumn) from mytable; 我已确认每行都有值。 (该列可以为空,这与下面的代码片段相关,但实际上所有行都具有非空值)
  • 我有这个模型对象:
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>() 查询获取对象,UUIDColumn 总是等于 Guid.Empty
  • 我尝试将类定义中的类型切换为 Byte[];总是null
  • 我尝试将类定义中的类型切换为 string;总是null
  • 同样适用于 UInt16[] 类型(GUID 可能存储为 16 位字的 blob,所以我也尝试了该类型)

如何使用 uuid 读取 sqlite-net-pcl 类型列中的值?

解决方法

我放弃了在 sqlite-net-pcl 中使用 ORM 功能并使用了这个查询:

db.executeScalar<byte[]>('select hex(uuidcolumn) from mytable where recordid=1');

我得到的是 72 个字节,它似乎代表了 Guid 的字符串表示中的 36 个 ASCII 字符(经常有一个字符是 2D,它是 - ASCII 集)。所以我认为后备存储是一个 blob,但它存储了 Guid 的文本表示,这很奇怪,但我可以从这里重建 Guid。

使用 this answer 并将该 blob 作为字符串获取,我最终得到了这个实现:

        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);  
        }

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...