使用 ObjectBox 自定义 ID

Custom ID with ObjectBox

我将 ObjectBox 与 Flutter 一起使用,但在每个 Entity.

上 ObjectBox 要求的强制性 int id 遇到了一些麻烦

在我的应用程序中,我使用 uuid package 使用自定义 ID,并将这些 Entity class 映射到我自己的 Domain classes 对 ObjectBox 实现进行抽象。

那些 Entity classes 具有 ObjectBox 要求的强制性 int id 我定义为 int obid 注释 @Id() 和我自己的 Domain id 定义为 String id,带有 @Unique() 注释。

当我需要通过 id 获取 Entity 时,它只会让我多做一些工作,但这没关系。问题是当我需要添加一个与另一个有关系的 Entity 时,因为我的 Domain classes 在我从 DomainEntity class,obid 被省略并默认为 0,然后 ObjectBox 尝试 persist/create 一个新的 Entity 并失败,因为id@Unique() 注释。我什至不想为关系创建一个新的 Entity。我想要的是创建一个 Entity 并只引用一个已经存在的 Entity 作为关系。

我认为实现它的方法是设置 relation.targetrelation.targetId 但在我的情况下,这不起作用,因为它不依赖于我的 id .

如何让我自己的 id 作为真实 ID 而不仅仅是 Unique 约束?

以下是 EntityDomain class 的一些示例:

文档模板实体:

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

  @Unique()
  String id;
  String title;
  double leftMargin;
  double topMargin;
  double rightMargin;
  double bottomMargin;
  DateTime? insertedAt;
  DateTime? updatedAt;
  final family = ToOne<DocumentFamilyEntity>();

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

  DocumentTemplate toDomain() => DocumentTemplate(
        id: UniqueId.fromUniqueString(id),
        title: DocumentTemplateTitle(title),
        leftMargin: leftMargin,
        topMargin: topMargin,
        rightMargin: rightMargin,
        bottomMargin: bottomMargin,
        insertedAt: insertedAt,
        updatedAt: updatedAt,
        family: family.target!.toDomain(),
      );

  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,
        insertedAt: template.insertedAt,
        updatedAt: template.updatedAt,
      )..family.target = DocumentFamilyEntity.fromDomain(template.family);
}

文档家族实体:

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

  @Unique()
  String id;
  String title;
  int sortOrder;
  DateTime? insertedAt;
  DateTime? updatedAt;

  DocumentFamilyEntity({
    required this.id,
    required this.title,
    required this.sortOrder,
    this.insertedAt,
    this.updatedAt,
  });

  DocumentFamily toDomain() => DocumentFamily(
        id: UniqueId.fromUniqueString(id),
        title: title,
        sortOrder: sortOrder,
        insertedAt: insertedAt,
        updatedAt: updatedAt,
      );

  factory DocumentFamilyEntity.fromDomain(DocumentFamily family) =>
      DocumentFamilyEntity(
        id: family.id.getOrCrash(),
        title: family.title,
        sortOrder: family.sortOrder,
        insertedAt: family.insertedAt,
        updatedAt: family.updatedAt,
      );
}

文档模板(域):

@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,
    DateTime? insertedAt,
    DateTime? updatedAt,
  }) = _DocumentTemplate;

  factory DocumentTemplate.initial() => DocumentTemplate(
        id: UniqueId(),
        title: DocumentTemplateTitle(''),
        leftMargin: 1.0,
        topMargin: 1.0,
        rightMargin: 1.0,
        bottomMargin: 1.0,
        family: DocumentFamily.initial(),
      );
}

文档家族(域):

@freezed
class DocumentFamily with _$DocumentFamily {
  factory DocumentFamily({
    required UniqueId id,
    required int sortOrder,
    required String title,
    DateTime? insertedAt,
    DateTime? updatedAt,
  }) = _DocumentFamily;

  factory DocumentFamily.initial() => DocumentFamily(
        id: UniqueId(),
        sortOrder: 0,
        title: '',
      );
}

您已经正确地假设您可以设置 relation.target(或 relation.targetId)- 它可以指向现有对象,在这种情况下 ObjectBox 不会尝试创建它。改编以下代码应该适合您:

final docTemplate = DocumentTemplateEntity(...)
final familyQuery = store.box<DocumentFamilyEntity>().query(DocumentFamilyEntity_.id.equals('unique ID of an existing family entity').build();

// and one of the following
docTemplate.family.target = familyQuery.findFirst(); 
// or
docTemplate.family.targetId = (familyQuery..limit = 1).findIds().firstOrNull;