【问题标题】:Windows Phone 8 SQLite database UpgradeWindows Phone 8 SQLite 数据库升级
【发布时间】:2014-05-22 09:33:08
【问题描述】:

我们的 Wp8 应用程序使用 Sqlite 作为数据库。我们有一个最近更新的封闭测试版。

我们的问题是,当我们修改数据库时,用户更新应用程序时,由于差异,他们得到了异常。 因此,我们需要以某种方式存储数据库版本,并在有新版本可用时对其进行升级。

最好/最简单的方法是什么?

【问题讨论】:

  • 现在,我也有同样的问题。有什么办法可以实现他的。如果是这样,请指导我。提前致谢。
  • 现在我们正在使用 azure 数据库和移动服务,这解决了(大部分)问题。

标签: database sqlite windows-phone-8 upgrade


【解决方案1】:

在 Android 中,这是由 SQLiteOpenHelper class 处理的,它在数据库中存储版本号(使用 PRAGMA user_version)并具有 onCreate/onUpdate 回调供应用处理这些情况。

查看the source 并实现类似的东西。

【讨论】:

  • 是的,这就是我要搜索的内容。唯一的问题是我不知道如何创建 onUpdate - 我不想丢失存储的数据。从表中添加或删除列不是问题,但是如果我们改变它的类型(比如从 sting 到 int)呢?有什么建议吗?
  • 那么你必须适当地转换它。具体如何取决于您的数据。
  • 那么你认为我们还需要存储所有旧类吗?没有它,我不知道旧的结构。
  • 转换器代码显然需要知道两个版本。
  • 这不是一个解决方案。
【解决方案2】:

当您更改数据库的结构时,您可以更改数据库文件名(base1.db、base2.db)中的版本。或者您可以将版本存储在IsolatedStorageSettings

【讨论】:

  • 谢谢,但这无济于事。我们不想丢失数据。
【解决方案3】:

作为对 SO 社区和帮助他人的小小感谢,我提供了用于处理架构更改的主要代码。请注意,这将处理从任何早期版本到最新版本的数据库升级(即使用户跳过其间的版本)。不处理数据库降级。我可能应该多做一些错误检查 | try/catch 语句。

在我的 sqlite 助手类中,我有以下声明(注意版本在首次创建数据库时设置为 1):

private SQLiteConnection _db;

// Increment this number whenever DB schema changes are made
private const int LATEST_DATABASE_VERSION = 3;

那么主要的升级方法是:

private void DoUpgradeDb(int oldVersion, int newVersion)
        {
            for (int vFrom = oldVersion; vFrom < newVersion; vFrom++)
            {
                switch (vFrom)
                {
                    case 1: // Upgrade from v1 to v2
                        UpgradeV1AlterPersonAddColumnAge();
                        break;
                    case 2: // Upgrade from v2 to v3
                        UpgradeV2CreateTableHobbies();
                        break;
                    default:
                        break;
                }
            }
            // Save the new version number to local storage
            App.AppSettingsService.SetDatabaseVersion(newVersion);
        }

正如您在上面看到的,我喜欢将每个版本中所做的单独更改放入自己的方法中,因此我可以将UpgradeV2CreateTableHobbies() 方法定义为:

    private void UpgradeV2CreateTableHobbies()
    {
        _db.CreateTable<Hobbies>();
    }

当然,如果数据库是从头开始创建的(例如新安装),您还需要记住进行更改。

当进行下一组架构更改时,您增加 LATEST_DATABASE_VERSION 常量。然后,我检查每次实例化我的 Sqlite 助手类时是否需要版本升级(因为我使用单例模式),您可以执行以下操作:

    private bool UpgradeDbIfRequired()
    {
        bool wasUpgradeApplied = false;
        // I wrote a GetDatabaseVersion helper method that reads the version (as nullable int) from the app settings.
        int? currentVersion = App.AppSettingsService.GetDatabaseVersion();
        if (currentVersion.HasValue && currentVersion.Value < LATEST_DATABASE_VERSION)
        {
                // Upgrade to latest version
                DoUpgradeDb(currentVersion.Value, LATEST_DATABASE_VERSION);
                wasUpgradeApplied = true;
        }
        else
        {
            // Already on latest version
            return false;
        }

        return wasUpgradeApplied;
    }

【讨论】:

    【解决方案4】:

    这可以在数据库中使用 PRAGMA user_version 来实现。源代码的头文件中应该有版本信息作为常量。

    每当更新数据库架构文件时,都应在架构文件和头文件中更新版本信息。

    上电时,使用 PRAGMA user_version 从 DB 读取 DB 版本,并与头文件中的版本进行比较。如果匹配,则继续正常操作。

    如果版本不匹配,则可以删除数据库并创建新数据库。创建的新数据库将具有新的版本号。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多