未调用Realm dotnet迁移回调

时间:2017-01-24 20:02:05

标签: xamarin realm database-migration

我正在尝试使用v0.81.0版本实现域迁移

当我在我的一个数据访问对象中安装并运行带有附加字段的应用程序的新版本时,它只是抛出异常(RealmMigrationNeededException)告诉我必须迁移,因为我有为我的一个数据访问对象添加了一个属性。这是我第一次尝试迁移,因此以前没有设置回调到模式版本

这是我的代码,任何人都可以看到任何问题。此处使用的加密密钥仅用于示例目的

        try
        {
            var config = new RealmConfiguration("MyExampleDatabase.realm");

            var encryptionKey = new byte[64] // key MUST be exactly this size
                {
              0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
              0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
              0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
              0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
              0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
              0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
              0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
              0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
                };

            config.EncryptionKey = encryptionKey;

            // Start of new code added
            config.MigrationCallback = (migration, oldSchemaVersion) =>
            {
                // do migration here!!
            };

            config.SchemaVersion = 1;
            // End of new code added
            var realm = Realm.GetInstance(config);
            return realm;
        }
        catch (Exception ex)
        {
            // Log error here
        }

2 个答案:

答案 0 :(得分:1)

Realm配置的SchemaVersion必须更改才能调用迁移回调。

迁移示例

初始RealmObject(SchemaVersion == 1)

public class POCO : RealmObject
{
    public string key { get; set; }
    public string value { get; set; }
}

初始应用程序(SchemaVersion == 1)

const ulong currentSchemaVersion = 1;
var config = new RealmConfiguration()
{
    SchemaVersion = currentSchemaVersion,
    MigrationCallback = (Migration migration, ulong oldSchemaVersion) =>
    {
        // initial app release / no schema migration
        // This will NOT be called
    }
};
var realm = Realm.GetInstance(config);
realm.WriteAsync((Realm r) =>
{
    var data = new POCO()
    {
        key = "1",
        value = "1"
    };
    r.Add(data);
});

RealmObject在新的应用版本中发生了变化:

更新了RealmObject(SchemaVersion == 2)

注意value的类型已从string更改为int

public class POCO : RealmObject
{
    public string key { get; set; }
    public int value { get; set; }
}

更新了应用程序(SchemaVersion == 2)

const ulong currentSchemaVersion = 2;
var config = new RealmConfiguration()
{
    SchemaVersion = currentSchemaVersion,
    MigrationCallback = (Migration migration, ulong oldSchemaVersion) =>
    {
        if (oldSchemaVersion > currentSchemaVersion)
        {
            throw new Exception($"SchemaVersion of {oldSchemaVersion} is unknown");
        }
        if (oldSchemaVersion <= 1)
        {
            // SchemaVersion = 1
            // initial app release / no schema migration
        }
        if (oldSchemaVersion < 2)
        {
            // SchemaVersion = 2,
            // POCO.value changed from string to int

            var newPOCOs = migration.NewRealm.All<POCO>();
            var oldPOCOs = migration.OldRealm.All("POCO");
            var count = newPOCOs.Count();
            for (int i = 0; i < count; i++)
            {
                var oldPOCO = oldPOCOs.ElementAt(i);
                var newPOCO = newPOCOs.ElementAt(i);
                newPOCO.value = int.Parse(oldPOCO.value);
            }
        }
    }
};
var realm = Realm.GetInstance(config);
realm.WriteAsync((Realm r) =>
{
    var data = new POCO()
    {
        key = "2",
        value = 2
    };
    r.Add(data);
});

答案 1 :(得分:1)

<强>摘要

迁移工作,即使旧版本的Realm早于它们。

加密没有区别。

<强>原始

@sushihangover是对的,但有更多的细微差别。

只需添加属性就不需要回调,除非您希望自定义逻辑填充它。该属性将自动添加到领域。

但是,为了确保您打算更改架构,最小迁移是将架构号设置为we document

似乎你可能有一个问题,你开始使用0.77.1。查看changelog, 0.77.2引入修复架构版本号的版本现在从0开始,而不是UInt64.MaxValue

然而:

使用测试结果进行更新

简单迁移

  1. 我使用0.77.1 nuget构建了一个应用程序并在iPhone上运行
  2. 我复制了解决方案,并通过首先删除Realm然后添加0.81.0软件包将我的副本更新为0.81.0。
  3. 在副本中,我添加了一个简单的整数属性。
  4. 正在运行已迁移的副本
  5. 这些结果让我感到有些惊讶 - 我想我需要明确设置SchemaVersion

    但后来我意识到默认SchemaVersion在0.81.0中为0可能有效,因为旧的UInt64.MaxValue被处理为未分配

    回调测试

    1. 采用上述两种解决方案,我添加了一个回调方法,如in our Migration docs所述。
    2. 没有调用迁移回调,毫不奇怪。
    3. 我明确设置了一个新的config.SchemaVersion,并调用了我的迁移回调。
    4. 底线 - 这一切都按预期工作。

      回调测试 - 纯粹在0.81.0 我重新阅读了一个问题,即你的迁移实验是,从0.77.1领域开始,但是在0.81.0。

      1. 我使用最小模式开始使用0.81.0并运行,因此创建了Realm。
      2. 我添加了一个属性和我的迁移回调。
      3. 我设置了SchemaVersion=1
      4. 我跑了,调用了迁移回调(暗示初始SchemaVersion为0)。
      5. 这让我对触发你的异常的实际情况感到有些困惑,因为看起来所有内容都按照文档记录并且预期为0.81.0,无论是从旧的0.71.1迁移还是从当前的0.81.0 Realm迁移。 / p>

        按照我在问题评论中提到的另一种理论,我尝试添加加密,看看是否有所不同(不)。