我需要将@PrimaryKey添加到由于白痴而缺少它的两个Realm模型中。通过直接关系或RealmLists在多个其他模型中引用了这些模型,两个模型之一也引用了另一个模型。

我的第一个想法是在迁移中重命名架构并手动复制数据,但是Realm提示该架构已链接到其他架构中,无法重命名。

两种模式都包含大约15000个对象,可以压缩为大约100个对象,它们是完全相同的,并且由于缺少@PrimaryKey而已被复制。

这些模型本身很简单:

class ModelA extends RealmObject {
     String primaryKey; // Is missing the @PrimaryKey annotation
     String someField;
     String someOtherField;
     Date someDate;
     ModelB relationToTheOtherProblematicModel;
}

class ModelB extends RealmObject {
    String primaryKey; // Is also missing the @PrimaryKey annotation
    // this class only contains String fields and one Date field
}

@PrimaryKey添加到两个类的primaryKey字段中时,如何迁移数据?

编辑以澄清:

这两个模式都包含多个完全相同的项目。

primaryKey | someField | someOtherField
------     | ------    | ------
A          | foo       | bar
A          | foo       | bar
A          | foo       | bar
A          | foo       | bar
B          | bar       | foo
B          | bar       | foo
B          | bar       | foo
C          | far       | boo
C          | far       | boo
C          | far       | boo

由于primaryKey可以唯一标识它们,因此可以删除这些重复项。当我添加@PrimaryKey批注并进行迁移时,Realm显然会提示重复的值。我需要删除这些重复项而不破坏其他模型中的链接。

最佳答案

您是否尝试过这样的事情:

RealmConfiguration config = new RealmConfiguration.Builder(this)
            .schemaVersion(6) //the new schema version
            .migration(new RealmMigration() {
                @Override
                public void migrate(DynamicRealm realm, long oldVersion, long newVersion) {

                    RealmSchema schema = realm.getSchema();
                    schema.get("ClassA").addPrimaryKey("primaryKey");
                    schema.get("ClassB").addPrimaryKey("primaryKey");
                }
            })
            .build();
Realm.setDefaultConfiguration(config);

编辑:
我根据this进行了编辑。这些是应该解决此问题的以下步骤:
1.创建新字段,请不要将其标记为主键。
2.使用转换为每个实例将新字段设置为唯一值
3.在新字段中添加索引。
4.将新字段设置为主键。
RealmConfiguration config = new RealmConfiguration.Builder(this)
            .schemaVersion(6) //the new schema version
            .migration(new RealmMigration() {
                @Override
                public void migrate(DynamicRealm realm, long oldVersion, long newVersion) {

                    RealmSchema schema = realm.getSchema();
                    schema.get("ClassA").addField("newKey", String.class)
                        .transform(new RealmObjectSchema.Function() {
                            @Override
                            public void apply(DynamicRealmObject obj) {
                                obj.set("newKey", obj.getString("primaryKey"));
                            }
                        })
                        .addIndex("newKey")
                        .addPrimaryKey("newKey");

                    schema.get("ClassB").addField("newKey", String.class)
                        .transform(new RealmObjectSchema.Function() {
                            @Override
                            public void apply(DynamicRealmObject obj) {
                                obj.set("newKey", obj.getString("primaryKey"));
                            }
                        })
                        .addIndex("newKey")
                        .addPrimaryKey("newKey");
                }
            })
            .build();
        Realm.setDefaultConfiguration(config);

08-18 10:04