React Native Realm DB - 嵌入式对象不适合我

问题描述 投票:0回答:3

在 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>
  );
};
react-native realm
3个回答
1
投票

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

,然后还要确保嵌入对象没有主键。


0
投票
如果有人对当前版本的领域(^12.5.0)有任何问题,我的解决方案是:

嵌入对象的类:

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 模式中。


-1
投票
感谢 Jay 的回答,并在更仔细地阅读文档后,我像这样更改了项目及其嵌入任务的创建,并且它有效:

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> ); };
    
© www.soinside.com 2019 - 2024. All rights reserved.