【问题标题】:SQLite Windows Phone character encoding not workingSQLite Windows Phone 字符编码不起作用
【发布时间】:2015-07-19 05:06:40
【问题描述】:

我正在开发一个带有 SQLite 数据库的 Windows Phone 8.1 应用程序来存储本地化字符串。为此,我使用 SQLite for Windows Phone 8.1 扩展,并且我正在使用 C# 进行编程。但是,当我将本地化字符串存储在数据库中时,“å”、“ö”等特殊字符在 SQLite 数据库中显示为“�”。

我已经尝试了以下方法:

1) 在将 C# 字符串存储到数据库之前将其转换为 UTF-8、UTF-16 或 Unicode,无需任何帮助。看来用 C# 编码字符串是没用的。

2) 使用 PRAGMA encoding="UTF-16" 设置 SQLite 数据库使用 UTF-16 编码;创建数据库时。编译指示已正确处理,但特殊字符仍为“�”。

我的假设是 SQLite for Windows Phone 8.1 扩展的 C++ 代码有问题。

在别处存储本地化字符串不是一种选择,那么我怎样才能获得 SQLite for Windows Phone 8.1 扩展来正确存储特殊字符?

C#代码:

public IEnumerable<IDictionary<string,object>> ExecuteQuery(string query)
{
    lock (LockObject)
    {
        var sqCommand = new SQLiteCommand(_sqLiteConnection) { CommandText = query };
        return sqCommand.ExecuteQueryEx();
    }
}

执行的查询是:

INSERT INTO LocalizedStrings (Id, LocalizedKey_Id, Language_Id, StringValue) VALUES (13,13,1053,'Sökområde');

以及 SQLiteCommand.ExecuteQueryEx 代码:

public IEnumerable<IDictionary<string,object>> ExecuteQueryEx()
{
    if (_conn.Trace)
    {
        Debug.WriteLine("Executing Query: " + this);
    }
    var result = new List<Dictionary<string,object>>();
    var stmt = Prepare();

    while (SQLite3.Step(stmt) == SQLite3.Result.Row)
    {
        var columnCount = SQLite3.ColumnCount(stmt);
        var row = new Dictionary<string,object>();

        for (var i = 0; i < columnCount; i++)
        {
            var columnName = Marshal.PtrToStringAnsi(SQLite3.ColumnName(stmt, i));
            var columnType = SQLite3.ColumnType(stmt, i);
            var value = ReadColEx(stmt, i, columnType);
            row.Add(columnName, value);
        }
        result.Add(row);
    }

    Finalize(stmt);

    return result;
}

【问题讨论】:

  • 分享您的代码以获得更好的答案和指导。

标签: c# sqlite encoding windows-phone-8.1


【解决方案1】:

似乎可以使用以下解决方案解决此问题: bug report at github

使用这种技术,我添加了一个带有特殊 Prepare2 方法的部分 SQLiteCommand 类,以将 CommandText 字符串转换为 UTF8 字节数组:

[DllImport("sqlite3", EntryPoint = "sqlite3_prepare_v2", CallingConvention = CallingConvention.Cdecl)]
private static extern SQLite3.Result Prepare2(IntPtr db, byte[] queryBytes, int numBytes, out IntPtr stmt, IntPtr pzTail);

private Sqlite3Statement Prepare2()
{
    IntPtr statement;
    var queryBytes = System.Text.Encoding.UTF8.GetBytes(CommandText);
    var result = Prepare2(_conn.Handle, queryBytes, queryBytes.Length, out statement, IntPtr.Zero);

    if (result != SQLite3.Result.OK)
    {
        throw SQLiteException.New(result, SQLite3.GetErrmsg(_conn.Handle));
    }

    BindAll(statement);
    return statement;
}

问题代码示例中的 'Prepare()' 方法被这个新的 'Prepare2()' 方法替换,现在,特殊字符正确地出现在 SQLite 数据库中。

【讨论】:

    猜你喜欢
    • 2013-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-19
    • 1970-01-01
    • 2013-03-24
    相关资源
    最近更新 更多