关系和嵌入式对象 — React Native SDK
一对一关系
一对一关系意味着一个对象最多与特定类型的另一个对象相关。要定义一对一关系,将属性类型指定为相关的 Realm 对象类型。
例子
在此示例中,Manufacturer
可生成单个 Car
:
class ToOneManufacturer extends Realm.Object { _id!: BSON.ObjectId; name!: string; car?: Car; static schema: Realm.ObjectSchema = { name: 'ToOneManufacturer', properties: { _id: 'objectId', name: 'string', // A manufacturer that may have one Car object car: 'Car?', }, }; } class Car extends Realm.Object { _id!: BSON.ObjectId; model!: string; miles?: number; static schema: Realm.ObjectSchema = { name: 'Car', properties: { _id: 'objectId', model: 'string', miles: 'int?', }, }; }
一对多关系
一对多关系表示一个对象可能与多个对象相关。要定义一/多对多关系,请指定一个属性,而其类型为对象模式中相关 Realm 对象类型的列表或数组。
例子
在此示例中,一个 Manufacturer
可生成多个 Car
模型:
class ToManyManufacturer extends Realm.Object { _id!: BSON.ObjectId; name!: string; cars!: Realm.List<LinkedCar>; static schema: Realm.ObjectSchema = { name: 'ToManyManufacturer', properties: { _id: 'objectId', name: 'string', // A manufacturer's related LinkedCar objects cars: 'LinkedCar[]', }, }; } class LinkedCar extends Realm.Object { _id!: BSON.ObjectId; model!: string; miles?: number; static schema: Realm.ObjectSchema = { name: 'LinkedCar', properties: { _id: 'objectId', model: 'string', miles: 'int?', // A car's related ToManyManufacturer objects manufacturer: { type: 'linkingObjects', objectType: 'ToManyManufacturer', property: 'cars', }, }, }; }
反向关系
反向关系将对象链接回在定义的对一或对多关系中引用该对象的任何其他对象。默认情况下,关系定义是单向的。您必须在对象模型中明确将属性定义为反向关系。
例如,对多关系“Manufacturer has many Cars”不会自动创建反向关系“Car belongs to Manufacturer”。如果您没有在对象模型中指定反向关系,则需要运行单独的查询来查找制造汽车的制造商。
定义反向关系属性
您可以使用 linkingObjects
为对象模式中的属性指定反向关系。如此,您便可像访问普通属性一样访问反向关系。
linkingObjects
属性反向链接到特定关系。您可以通过对象类型和关系的属性名称来指定要反向链接的关系。
例子
在此示例中, ManufacturerInverse
对象的cars
属性与CarInverse
对象的 Realm .List具有多对多关系。 它包含与制造商关联的所有汽车。
CarInverse
对象的 manufacturer
属性会反转此关系。manufacturer
属性会自动更新以引用回其 cars
属性中包含汽车对象的任一 ManufacturerInverse
对象。
class ManufacturerInverse extends Realm.Object { _id!: BSON.ObjectId; name!: string; cars!: Realm.List<CarInverse>; static schema: Realm.ObjectSchema = { name: 'ManufacturerInverse', properties: { _id: 'objectId', name: 'string', // A manufacturer's related CarInverse objects cars: 'CarInverse[]', }, }; } class CarInverse extends Realm.Object { _id!: BSON.ObjectId; model!: string; manufacturer!: Realm.List<ManufacturerInverse>; miles?: number; static schema: Realm.ObjectSchema = { name: 'CarInverse', properties: { _id: 'objectId', model: 'string', miles: 'int?', // A car's related ManufacturerInverse objects manufacturer: { type: 'linkingObjects', objectType: 'ManufacturerInverse', property: 'cars', }, }, }; }
查找代码中的链接对象
您可以调用该对象的 Realm.Object.linkingObjects() 方法来查找链接到给定对象的所有对象。当您要访问特定关系的所有链接对象而不向对象模式添加属性时,此功能非常有用。
例子
本示例中,我们有 LinkedCar
对象模型,其中没有类型为“linkingObjects”的 manufacturer
字段。有人创建了多个制造商和汽车对象,将新创建的汽车添加到制造商的 cars
字段中。
我们可以使用 linkingObjects()
方法查找汽车制造商。该方法返回链接到汽车的对象的结果集合。在该示例中,只有一家制造商生产 Sentra 车型,因此,我们可以推断该制造商的名称是 Nissan。
要查找生产特定汽车的制造商:
调用
linkingObjects()
将 manufacturer 类名和“cars”字段作为参数进行传递
const getLinkedManufacturer = (car: LinkedCar): string => { const manufacturer = car.linkingObjects<ToManyManufacturer>( 'ToManyManufacturer', 'cars', )[0]; // Returns 'Nissan', as only one manufacturer is linked // to this car object. return manufacturer.name; };
嵌入式对象
嵌入式对象是一种特殊类型的Realm 对象,用于对有关特定对象的复杂数据进行建模。 嵌入式对象与关系类似,但它们提供了额外的约束,并且更自然地映射到非规范化的MongoDB document model 。
Realm 强制执行唯一的所有权约束,将每个嵌入式对象视为单个特定父对象内的嵌套数据。嵌入式对象继承其父对象的生命周期,不能作为独立的 Realm 对象存在。这意味着嵌入式对象不能有主键,并且如果删除嵌入式对象的父对象,Realm 会自动删除嵌入式对象。
提示
嵌入式对象类型可重用、可组合
您可以在多个父对象类型中使用相同的嵌入式对象类型,也可以在其他嵌入式对象中嵌入对象。您甚至可以在其自身的定义中将嵌入式对象类型以递归方式引用为一个可选属性。
Realm 对象模型
要定义嵌入式对象,请将 embedded
设置为 true
。您可以采用与定义关系相同的方式,从父对象类型中引用嵌入式对象类型:
class Manufacturer extends Realm.Object { _id!: BSON.ObjectId; name!: string; cars!: Realm.List<CarWithEmbed>; warranties!: Realm.List<Warranty>; static schema: Realm.ObjectSchema = { name: 'Manufacturer', properties: { _id: 'objectId', name: 'string', cars: 'CarWithEmbed[]', // Embed an array of objects warranties: 'Warranty[]', }, }; } class CarWithEmbed extends Realm.Object { _id!: BSON.ObjectId; model!: string; miles?: number; warranty?: Warranty; static schema: Realm.ObjectSchema = { name: 'CarWithEmbed', properties: { _id: 'objectId', model: 'string', miles: 'int?', // Embed one object warranty: 'Warranty?', }, }; } class Warranty extends Realm.Object { name!: string; termLength!: number; cost!: number; static schema: Realm.ObjectSchema = { name: 'Warranty', embedded: true, properties: { name: 'string', termLength: 'int', cost: 'int', }, }; }
重要
嵌入式对象不能有主键。