【问题标题】:Many-to-Many Relationships in Realm using Objective-C使用 Objective-C 实现领域中的多对多关系
【发布时间】:2017-06-13 23:55:04
【问题描述】:

我花了好几个小时试图弄清楚如何使用 Objective-C 在 Realm 中设置对象关系模型和创建/删除多对多关系。文档帮助不大。关于是否使用 RLMArray 或 RLMLinkingObjects,我可以使用一些指导...我正在从 Core Data 关系数据库迁移,并且有几个我正在尝试建模的多对多关系,这对我来说根本没有意义。唯一显示多对多关系的文档显示了一个与它自己的两个属性相关的类。其中一个属性使用 RLMArray,另一个使用 RLMLinkingObjects。这对我来说毫无意义,因为多对多关系应该是双向的,并且应该能够通过任一方添加或删除关系。也许我想错了,但我迷路了,希望能得到一些帮助。

【问题讨论】:

  • RLMArray 是指向多个对象的单向链接,RLMLinkingObjects 是指向链接到该对象的对象的单向反向链接。可以通过RLMArray修改关系,它会自动管理其逆关系(对应RLMLinkingObjects)。如果您需要修改与目标的关系,则可以使用通过主键跨链接对象的链接查询来找到具有RLMArray 的对象。
  • 在这一点上,您能指导我看一些演示这一点的代码吗?我并不是想找人为我做我的工作——我真的花了几个小时尽可能彻底地研究它,但不知道如何设置这一切。
  • ...好吧,我会尝试从文档中将一些 sn-ps 放在一起。我不精通任何 iOS(尤其是如果您看到我的帖子历史记录和标签)
  • 我很感激 - 但我已经搜索了文档,这对我来说仍然没有任何意义。我想我只是没有掌握它。
  • 差不多,取决于哪一边指向哪一边。反向是自动管理的。例如,您可以将 dogs.owner 建模为 RLMArray,但您也可以将 person.dogs 建模为此类。通常,person.dogs 更有意义。 RLMArray 是您添加属于该对象的内容的位置,如果您向 RLMArray 添加/删除任何内容,链接的内容将自动管理。

标签: objective-c many-to-many realm rlmarray rlmlinkingobjects


【解决方案1】:

Many Realm 中的关系使用RLMArray 建模。然而,每个一对一和一对多关系都会创建其自己的对应逆向关系,由RLMLinkingObjects(链接到当前对象的对象)建模。

所以RLMArray 是指向多个对象的单向链接,RLMLinkingObjects 是指向链接到该对象的对象的单向反向链接。可以通过RLMArray修改关系,它会自动管理其逆关系(对应RLMLinkingObjects)。

如果您需要修改与目标的关系,则可以通过主键在链接对象之间使用链接查询来找到具有RLMArray 的对象。

import <Realm/Realm.h>

@class Person;

// Dog model
@interface Dog : RLMObject
@property NSInteger id;
@property NSString *name;
@property (readonly) RLMLinkingObjects *owners;
@end
RLM_ARRAY_TYPE(Dog) // define RLMArray<Dog>

// Person model
@interface Person : RLMObject
@property NSInteger            id;
@property NSString             *name;
@property NSDate               *birthdate;
@property RLMArray<Dog *><Dog> *dogs;
@end
RLM_ARRAY_TYPE(Person) // define RLMArray<Person>

// Implementations
@implementation Dog
+ (NSDictionary *)linkingObjectsProperties {
    return @{
        @"owners": [RLMPropertyDescriptor descriptorWithClass:Person.class propertyName:@"dogs"],
    };
}

+ (NSString *)primaryKey {
    return @"id";
}

+ (NSArray *)indexedProperties {
  return @[@"name"];
}
@end

@implementation Person
+ (NSString *)primaryKey {
    return @"id";
}

+ (NSArray *)indexedProperties {
  return @[@"name"];
}
@end

所以当你在事务中修改person.dogs,那么dog.owners会自动更新。

RLMRealm *realm = [RLMRealm defaultRealm];
[realm transactionWithBlock:^{
    Person *jim = [[Person objectsWhere:@"name == 'Jim'"] firstObject];
    // Jim is owner of Rex 
    Dog * rex = [[Dog objectsWhere:@"name == 'Rex'"] firstObject];
    [jim.dogs addObject:rex]; // <-- now rex's `owners` contains `jim`
}];

您可以阅读有关 Realm 中关系的更多信息here

【讨论】:

  • 一个人可以养多只狗。之后,狗并不真正关心指向它的是一个还是多个,它总是被建模为链接对象,即 0..*
  • RLMLinkingObjects 是一个列表,所以从技术上讲是的,在这个模型中,一个 Dog 可以有多个所有者。它确实将其限制为 1 个所有者,这是肯定的。
  • 那么Dog需要指定Person *owner;(不是数组,因为你说的是​​one),然后是Person 将有名为 dogsRLMLinkingObjects* 字段。
  • RLMArray* 为许多链接建模。 SomeObject* 模型 ONE 链接。 RLMLinkingObjects* 模型反向链接。
  • 其实,那么Person中的dogs字段只能使用RLMLinkingObjects*,因为它是ownerinverse链接。从技术上讲,您可以并排管理多个链接,但是拥有两个链接而不是自动管理另一个方向的链接会使您的生活变得更加复杂。但这都是我在答案底部链接的文档中的全部内容。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-05-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多