2

我正在构建一个应用程序,其中 aDocument属于DocumentTemplatea DocumentFamily

我正在为应用程序处理基本的 CRUD 操作,我需要一种watchDocumentTemplateById方法来获取 a 流,DocumentTemplate但我还需要观看它的DocumentFamily.

问题是我不知道如何嵌套这两个流,以便在更新 aDocumentFamily时,DocumentTemplate将更新DocumentFamily.

如果有人能告诉我正确的方法,我将不胜感激。我使用 Flutter 和 ObjectBox 作为我的本地数据库。

这是watchDocumentTemplateById我开始实施的方法(未完成):

@override
Stream<Either<DocumentTemplateFailure, DocumentTemplate>>
      watchDocumentTemplateById(UniqueId templateId) {
    return _box
        .query(DocumentTemplateEntity_.id.equals(templateId.getOrCrash()))
        .watch(triggerImmediately: true)
        .map((query) {
      final templateEntity = query.findFirst();

      if (null != templateEntity) {
        final familyOrFailureStream =
            _documentFamilyRepository.watchDocumentFamilyById(
                UniqueId.fromUniqueString(templateEntity.familyId));

        familyOrFailureStream.listen((familyOrFailure) {
          return familyOrFailure.fold(
            (failure) =>
                DocumentTemplateFailure.familyFailure(familyFailure: failure),
            (family) => templateEntity.toDomain(family: family),
          );
        });
      }
      return left(const DocumentTemplateFailure.notFound());
    });
  }

以及上面提到的类(DocumentTemplate、DocumentTemplateEntity、DocumentFamily 和 DocumentFamilyEntity):

文档模板:

@freezed
class DocumentTemplate with _$DocumentTemplate {
  factory DocumentTemplate({
    required UniqueId id,
    required DocumentTemplateTitle title,
    required double leftMargin,
    required double topMargin,
    required double rightMargin,
    required double bottomMargin,
    required DocumentFamily family,
  }) = _DocumentTemplate;
}

文档模板实体:

@Entity()
class DocumentTemplateEntity {
  @Id()
  int obid = 0;

  @Unique()
  String id;
  String title;
  double leftMargin;
  double topMargin;
  double rightMargin;
  double bottomMargin;
  String familyId;

  DocumentTemplateEntity({
    required this.id,
    required this.title,
    required this.leftMargin,
    required this.topMargin,
    required this.rightMargin,
    required this.bottomMargin,
    required this.familyId,
  });

  DocumentTemplate toDomain({
    required DocumentFamily family,
  }) =>
      DocumentTemplate(
        id: UniqueId.fromUniqueString(id),
        title: DocumentTemplateTitle(title),
        leftMargin: leftMargin,
        topMargin: topMargin,
        rightMargin: rightMargin,
        bottomMargin: bottomMargin,
        family: family,
      );

  factory DocumentTemplateEntity.fromDomain(DocumentTemplate template) =>
      DocumentTemplateEntity(
        id: template.id.getOrCrash(),
        title: template.title.getOrCrash(),
        leftMargin: template.leftMargin,
        topMargin: template.topMargin,
        rightMargin: template.rightMargin,
        bottomMargin: template.bottomMargin,
        familyId: template.family.id.getOrCrash(),
      );
}

文档族:

@freezed
class DocumentFamily with _$DocumentFamily {
  factory DocumentFamily({
    required UniqueId id,
    required int position,
    required String name,
  }) = _DocumentFamily;
}

文档家庭实体:

@Entity()
class DocumentFamilyEntity {
  @Id()
  int obid = 0;

  @Unique()
  String id;
  String name;
  int position;

  DocumentFamilyEntity({
    required this.id,
    required this.name,
    required this.position,
  });

  DocumentFamily toDomain() => DocumentFamily(
        id: UniqueId.fromUniqueString(id),
        name: name,
        position: position,
      );

  factory DocumentFamilyEntity.fromDomain(DocumentFamily family) =>
      DocumentFamilyEntity(
        id: family.id.getOrCrash(),
        name: family.name,
        position: family.position,
      );
}

提前致谢 !

编辑 :

我试图自己解决它并找到了该switchMap方法,该方法似乎将两个流合并为一个,但我不完全确定它是否可以在这里使用更新的watchDocumentTemplateById方法:

ref.:如何在 Dart 中嵌套 Streams(将 Streams 映射到 Stream 事件)?

  @override
  Stream<Either<DocumentTemplateFailure, DocumentTemplate>>
      watchDocumentTemplateById(UniqueId templateId) {
    return _box
        .query(DocumentTemplateEntity_.id.equals(templateId.getOrCrash()))
        .watch(triggerImmediately: true)
        .switchMap((query) {
      final templateEntity = query.findFirst();
      // if(null == templateEntity) return ??? DocumentTemplateFailure.notFound();
      final familyId = UniqueId.fromUniqueString(templateEntity!.familyId);

      return _documentFamilyRepository.watchDocumentFamilyById(familyId).map(
            (failureOrFamily) => failureOrFamily.fold(
              (failure) => left(
                DocumentTemplateFailure.familyFailure(familyFailure: failure),
              ),
              (family) => right(
                templateEntity.toDomain(family: family),
              ),
            ),
          );
    });
  }
4

1 回答 1

1

您是否考虑过直接在DocumentFamilyDocumentTemplate类上使用@Entity?请参阅使用 package 显示它的示例freezed

在任何情况下,您都可能需要将实体之间的链接表示为ObjectBox 关系,而不仅仅是一个普通的 ID 字段。

然后 box.query().link() 创建跨实体的查询。如果你watch()是那个,它会在基础实体以及所有链接实体的变化时触发。

于 2021-07-14T05:36:10.897 回答