将主键添加到RLMObject需要迁移,任何想法如何?

我正在使用Realm.io作为持久存储的iOS应用程序。 我刚刚通过添加一个主键更新了我的一个自定义RLMObject子类。

当我运行该应用程序,我得到一个错误告诉我,我需要添加迁移步骤:

'Migration is required for object type 'MY_REALM_OBJECT' due to the following errors: - Property 'property_name' has been made a primary key.' 

我有其他的迁移代码,但在Realm文档中找不到关于如何将主键添加到RLMObject的任何内容。

有人知道怎么做吗?

您需要使用键“primaryKeyProperty”,并将值设置为newObject的迁移块中的RLMObject属性名称。 primaryKeyProperty是需要迁移的RLMObjectSchema属性的名称。

 [RLMRealm setSchemaVersion:kLatestSchemaVersion forRealmAtPath:theRealmPath withMigrationBlock:^(RLMMigration *migration, NSUInteger oldSchemaVersion) { if ( oldSchemaVersion < kLatestSchemaVersion ) { [migration enumerateObjects:MyRealmClass.className block:^(RLMObject *oldObject, RLMObject *newObject) { newObject[@"primaryKeyProperty"] = @"propertyName"; }]; } }]; 

我有其他的迁移代码,但在Realm文档中找不到关于如何将主键添加到RLMObject的任何内容。

你已经成为主键! Realm文档在“自定义模型”一节中介绍了这一点。

由于向模型添加/修改主键需要更新数据库文件(数据库中该表/列的每个值都将被编入索引),因此需要更新模式版本。

主键必须是唯一的。 如果所有值都是唯一的,则Realm将自动为您应用迁移,因此不需要对迁移块中的property_name属性进行任何更改。

如果property_name值不是全部都是唯一的,则需要在迁移块中使它们唯一。 在Realm迁移块中更改数据的方式是遍历现有对象,并使用带键的下标在newObject上设置值:

 [RLMRealm setSchemaVersion:1 forRealmAtPath:realmPath withMigrationBlock:^(RLMMigration *migration, NSUInteger oldSchemaVersion) { if (oldSchemaVersion < 1) { __block NSInteger incrementingPrimaryKeyValue = 0; // The enumerateObjects:block: method iterates // over every 'MY_REALM_OBJECT' object stored in the Realm file [migration enumerateObjects:@"MY_REALM_OBJECT" block:^(RLMObject *oldObject, RLMObject *newObject) { // set the primary key to a unique value newObject[@"property_name"] = @(incrementingPrimaryKeyValue++); }]; } }]; 

要了解有关迁移的更多信息,请阅读Realm文档的“迁移”部分。

在Swift中,我通过使用以下代码成功地将一个主键添加到我的领域:

 let config = Realm.Configuration( // Set the new schema version. This must be greater than the previously used // version (if you've never set a schema version before, the version is 0). schemaVersion: 1, // Set the block which will be called automatically when opening a Realm with // a schema version lower than the one set above migrationBlock: { migration, oldSchemaVersion in var sharedUserID = "" migration.enumerate(AdAccount.className()) { oldObject, newObject in if oldSchemaVersion < 1 { // Realm will automatically detect new properties and removed properties // And will update the schema on disk automatically sharedUserID = oldObject!["userID"] as! String newObject!["compoundKey"] = oldObject!["compoundkey"] } } migration.enumerate(AdCampaign.className()) { oldObject, newObject in if oldSchemaVersion < 1 { // Realm will automatically detect new properties and removed properties // And will update the schema on disk automatically let id = oldObject!["id"] as! String let dateRange = oldObject!["daterange"] let userID = sharedUserID newObject!["dateRange"] = dateRange newObject!["userID"] = userID newObject!["compoundKey"] = "\(id)-\(dateRange)-\(userID)" } } print("Migration complete.") }) // Tell Realm to use this new configuration object for the default Realm Realm.Configuration.defaultConfiguration = config let realm = try! Realm() } 

您需要确保使用主键的名称并使用oldObject属性设置它的值。 每个主键都必须是唯一的。 正如您在示例中所看到的,此主键由三个值组成,以使其唯一。