如何在 Xamarin Forms 应用程序中为现有用户覆盖 sqlite 数据库?

How to overwrite sqlite database for existing users in a Xamarin Forms app?

我们有一个 Xamarin Forms 应用。

我们有一些现有用户自去年以来一直在使用该应用程序,其中数据库文件名为 MyAppName.db

我们新的应用程序策略要求我们将 .db (Sqlite) 与应用程序一起包含在内,以确保我们可以包含持久信息并且在您安装应用程序时不需要互联网,这意味着我们希望覆盖 db 文件现有用户。

在我们发布数据库文件现在为 MyNewDbFile.db 的新更改后,我们的用户抱怨他们看不到任何数据,应用程序不会崩溃.

我们捕获错误报告,我们可以在我们的工具中看到一个常见错误,指出“行值被误用”,快速搜索表明该值不存在,因此“SELECT * FROM TABLE WHERE COLUMNAME" 查询不起作用导致异常。

我们可以确认我们正在使用

Xamarin.Forms version 4.5.x

sqlite-net-sqlcipher version 1.6.292

我们没有任何复杂的逻辑,也看不出导致这种情况的非常具体的原因,因为这不是我们从 Alpha 通道或 TestFlight 测试我们的应用程序时产生的。

我们调查了问题的核心,可以确认问题制造者是设备文化信息。

我们一直在使用英语作为设备语言进行测试,但是当人们使用英语以外的任何其他语言使用该应用程序时,查询会导致异常。

我们使用 Xamarin Essentials 库来获取设备位置(可选)。

纬度和经度 return 是特定于文化的。

因此,如果您在设备上使用西班牙语,则纬度和经度信息的格式是 ,(逗号)而不是 . (点).

That is, a Latitude value is something similar to 77.1234 where it is separated by a . (dot)

However for users with different region settings on device, the format would change to 77,1234 as value where it is separated by a , (comma).

查询要求我们将值作为字符串,并且当不以 . 分隔时。 (点)执行失败:

查询:

if (deviceLocation != null)
   queryBuilder.Append($" ORDER BY((Latitude - {deviceLocation.Latitude})*(Latitude - {deviceLocation.Latitude})) +((Longitude - {deviceLocation.Longitude})*(Longitude - {deviceLocation.Longitude})) ASC");

其中 deviceLocation 对象的类型 Xamarin.Essentials.Location 具有双纬度和经度值,但当用作字符串时或者即使您明确地执行 deviceLocation.Latitude.ToString(),它也会 return 根据设备格式化的值 CultureInfo

我们可以确认问题是由于格式类型不匹配导致查询抛出异常,在return中体验就好像没有数据。