关系 - C++ SDK
在定义关系时,Realm 不采用关系数据库中的桥接表或显式联接方式。Realm 通过嵌入式对象或其他 Realm 对象的引用属性来处理关系。您可以直接读取和写入这些属性。因此,查询关系与查询其他属性一样高效。
关系类型
Realm 支持to-one 、 to-many和反向关系。 Realm 还提供了一种特殊类型的对象,称为嵌入式对象,它在概念上类似于关系,但提供了额外的约束。
对一关系
一对一关系是指一个对象与另一个对象相关。 您可以在 Realm 对象类型的 Realm 对象模型中为其定义关系。指定一个属性,其类型为相关 Realm 对象类型。 例如,狗可能与最喜欢的玩具存在对一关系。
对多关系
对多关系是指一个对象与多个其他对象相关。在 Realm 中,对多关系是对其他对象的引用列表。例如,一个人可能会养很多只狗。
您可以将两个 Realm 类型之间的对多关系表示为列表、映射或集。 列表、映射和集合是可变的:在写事务(write transaction)中,您可以在这些collection类型中添加和删除元素。列表、映射和集与查询无关,它们被声明为对象模型的属性。
反向关系
Realm 中的关系定义是单向的。反向关系将对象链接回引用它的对象。
反向关系属性是一种自动反向链接关系。 每当在对应的一对多列表或一对一关系属性中添加或删除对象时,Realm 都会自动更新隐式关系。 您无法手动设置反向关系属性的值。
声明关系属性
定义对一关系
一对一关系将一个属性映射到另一种Realm 对象类型的单个实例。例如,您可以将一只最多有一个最喜欢的玩具的狗建模为一对一的关系。
将关系字段设置为 null 会删除对象之间的连接。 但是,Realm 不会删除引用的对象,除非它是嵌入式对象。
重要
对一关系必须是可选的
在对象模型中声明对一关系时,它必须是一个可选属性。如果您尝试建立所需的对一关系,Realm 会在运行时引发异常。
struct FavoriteToy { realm::primary_key<realm::uuid> _id; std::string name; }; REALM_SCHEMA(FavoriteToy, _id, name) struct Dog { realm::primary_key<realm::uuid> _id; std::string name; int64_t age; // Define a relationship as a link to another SDK object FavoriteToy* favoriteToy; }; REALM_SCHEMA(Dog, _id, name, age, favoriteToy)
定义对多关系
对多关系将一个属性映射到另一种Realm 对象类型的零个或多个实例。例如,您可以将具有任意数量员工的公司建模为对多关系。
struct Company { int64_t _id; std::string name; // To-many relationships are a list, represented here as a // vector container whose value type is the SDK object // type that the list field links to. std::vector<Employee*> employees; }; REALM_SCHEMA(Company, _id, name, employees)
定义反向关系
要定义反向关系,请在Realm 对象模型中使用 linking_objects
。linking_objects
定义指定了反向关系的Realm 对象类型和属性名称。
在此示例中,我们定义与Person
具有一对一关系的Dog
。Dog
通过其owners
属性与任何Person
对象具有反向关系。
struct Dog; struct Person { realm::primary_key<int64_t> _id; std::string name; int64_t age = 0; Dog* dog; }; REALM_SCHEMA(Person, _id, name, age, dog) struct Dog { realm::primary_key<int64_t> _id; std::string name; int64_t age = 0; linking_objects<&Person::dog> owners; }; REALM_SCHEMA(Dog, _id, name, age, owners)