在 React Native Realm 数据库(“realm”:“11.0.0”)上工作,我无法在here 中记录嵌入式对象。
我的错误是:
ERROR Exception in HostFunction: Embedded objects cannot be created directly.
如果您愿意,请在下面找到您可以复制/粘贴以重现问题的代码。如果您取消注释“embedded: true”,则此一对多关系示例有效。
import React from "react";
import { View, Text } from "react-native";
import Realm from "realm";
export class Project extends Realm.Object<Project> {
public _id: number;
public name: string;
public tasks: Realm.List<Task>;
static schema = {
name: "Project",
primaryKey: "_id",
properties: {
_id: "int",
name: "string",
tasks: { type: "list", objectType: "Task" },
},
};
}
export class Task extends Realm.Object<Task> {
public description: string;
static schema = {
name: "Task",
embedded: true, // uncomment
properties: {
description: "string",
},
};
}
(async () => {
let realm: any;
try {
realm = await Realm.open({
inMemory: true,
schema: [Project, Task],
});
} catch (e) {
console.error(e.message);
}
try {
realm.write(() => {
const t1 = realm.create(Task, {
description: "T1",
});
const t2 = realm.create(Task, {
description: "T2",
});
realm.create(Project, {
_id: 1,
name: "P1",
tasks: [t1, t2],
});
});
} catch (e) {
console.error(e.message);
}
console.log(JSON.stringify(realm.objects(Project), null, 3));
realm.close();
})();
export const App = () => {
return (
<View style={{ flex: 1, justifyContent: "center", alignItems: "center" }}>
<Text style={{ fontSize: 25 }}>Please look at the console</Text>
</View>
);
};
Realm 对象和 Realm 嵌入对象之间有一个重要的区别:
Realm 对象是一个单独的、独立的对象,由 Realm 直接管理。
嵌入式对象就是这样;嵌入到父对象中。它不是一个单独的、独立的对象,仅由 Realm 通过其父对象进行管理。因此,嵌入式对象无法直接写入 Realm。
如果没有父对象,嵌入对象就不存在。不能直接存储在Realm中;必须将其添加到其父对象,然后必须存储父对象(或者可以将其添加到已存在的父对象)。
总体而言,嵌入式对象实际上是父级架构的一部分,当父级被删除时,它的嵌入式对象也会被删除。
此外,嵌入对象只能通过父对象进行查询;例如,假设一个 Person 对象有一个嵌入的 Dog 对象。如果你想找一个养狗的人,名字叫spot,那就是(伪代码)
let somePerson = realm.query on the personObject.embeddedDog.name == "spot"
请注意
嵌入对象映射到父类型的嵌入文档 架构。此行为与常规 Realm 对象不同,后者映射 到他们自己的 MongoDB 集合。所以这个
schema: [Project, Task],
无法工作,因为 Task
是
Project
架构的一部分
编辑
一个例子是拥有多个地址的企业。地址本身不需要是单独管理的对象,因为它们直接与父业务相关。这是一个业务对象,其中将包含几个嵌入的地址对象
const BusinessSchema = {
name: "Business",
primaryKey: "_id",
properties: {
_id: "objectId",
name: "string",
addresses: { type: "list", objectType: "Address" },//array of embedded objects
},
};
然后嵌入的地址对象看起来像这样
const AddressSchema = {
name: "Address",
embedded: true, // default: false
properties: {
street: "string?",
city: "string?",
country: "string?",
postalCode: "string?",
},
};
请注意,嵌入对象必须设置为 embedded: true
,然后还要确保嵌入对象没有主键。
嵌入对象的类:
import { ObjectSchema } from 'realm';
import { Realm } from '@realm/react';
export default class AddressEmbedded extends Realm.Object<AddressEmbedded> {
cep?: string;
street?: string;
number?: string;
complement?: string;
neighborhood?: string;
city?: string;
state_sigla?: string;
static schema: ObjectSchema = {
name: 'AddressEmbedded',
embedded: true,
properties: {
cep: 'string?',
street: 'string?',
number: 'string?',
complement: 'string?',
neighborhood: 'string?',
city: 'string?',
state_sigla: 'string?',
},
};
}
接收嵌入对象的类:
import { ObjectSchema } from 'realm';
import { Realm } from '@realm/react';
import AddressEmbedded from './AddressEmbedded';
class ClentSchema extends Realm.Object<ClentSchema> {
_id!: Realm.BSON.ObjectId;
id_api?: string;
name?: string;
cpf?: string;
cnpj?: string;
order_allow?: boolean;
corporate_name?: string;
fantasy_name?: string;
state_registration?: string;
additional_Information?: string;
phone1?: string;
phone2?: string;
email?: string;
client_banner_photo?: string;
identification_document_photo?: string;
createdAt: Date = new Date();
clientUser?: string[];
address?: AddressEmbedded;
static schema: ObjectSchema = {
name: 'client',
properties: {
_id: 'objectId',
id_api: 'string?',
name: { type: 'string', indexed: true, optional: true },
cpf: { type: 'string', indexed: true, optional: true },
cnpj: { type: 'string', indexed: true, optional: true },
order_allow: { type: 'bool', default: true },
corporate_name: { type: 'string', indexed: true, optional: true },
fantasy_name: { type: 'string', indexed: true, optional: true },
state_registration: 'string?',
additional_Information: 'string?',
phone1: 'string?',
phone2: 'string?',
email: 'string?',
client_banner_photo: 'string?',
identification_document_photo: 'string?',
clientUser: 'string?[]',
address: 'AddressEmbedded?',
},
primaryKey: '_id',
};
}
export default ClentSchema;
我将这两个模式添加到 RealmProvider 模式中。
realm.write(() => {
realm.create("Project", {
_id: 1,
name: "P1",
tasks: [
{
description: "T1",
},
{
description: "T2",
},
],
});
});
但是当我使用类和构造函数或类和静态生成()对对象进行建模时,我仍然无法创建嵌入对象。如果您有此类的工作示例,请发布。更新(25/03/2023):更明确地说,如何修改下面的代码以使嵌入功能起作用?但如果可能的话,TASK 是一个带有构造函数的类。
如果没有“embedded: true,”行,此代码的输出是:
{“_id”:“641e5fdebde518d4ac0e7665”,“名称”:“P1”,“任务”: [{“描述”:“T1”},{“描述”:“T2”}]}使用“embedded: true”,此代码的输出是:
HostFunction 中出现错误异常:无法创建嵌入对象 直接。
import React from "react";
import { View, Text } from "react-native";
import Realm from "realm";
export class Project extends Realm.Object<Project> {
public _id: Realm.BSON.ObjectId;
public name: string;
public tasks: Realm.List<Task>;
static schema = {
name: "Project",
primaryKey: "_id",
properties: {
_id: "objectId",
name: "string",
tasks: { type: "list", objectType: "Task" },
},
};
constructor(realm: Realm, name: string, tasks: Task[] = []) {
super(realm, {
_id: new Realm.BSON.ObjectId(),
name: name,
tasks: tasks,
});
}
}
export class Task extends Realm.Object<Task> {
public description: string;
static schema = {
name: "Task",
embedded: true, // <==============================
properties: {
description: "string",
},
};
constructor(realm: Realm, description: string) {
super(realm, {
description: description,
});
}
}
(async () => {
let realm: any;
try {
realm = await Realm.open({
inMemory: true,
schema: [Project, Task],
});
} catch (e) {
console.error(e.message);
}
try {
realm.write(() => {
new Project(realm, "P1", [new Task(realm, "T1"), new Task(realm, "T2")]);
});
} catch (e) {
console.error(e.message);
}
for (const item of realm.objects(Project)) {
console.log(item.toJSON());
}
realm.close();
})();
export const App = () => {
return (
<View style={{ flex: 1, justifyContent: "center", alignItems: "center" }}>
<Text style={{ fontSize: 25 }}>Please look at the console</Text>
</View>
);
};