хранение вложенной структуры данных в поле объектов с помощью метода преобразования типов (.toObjectBox)

#flutter #clean-architecture #objectbox #flutter-objectbox

Вопрос:

Я думаю, самое лучшее (только?) способ состоит в том, чтобы создать отдельное поле для вложенной структуры, а затем создать отношение от родителя (ОДНОГО) к детям (МНОГИМ).

Однако моя проблема заключается в том, как реализовать .toObjectBox() метод преобразования модели данных моего домена в модель данных ObjectBox. Есть ли что-нибудь похожее Either в пакете dartz (возвращает объект с левой или правой стороны), который одновременно переносит 2 объекта?

Так и с объектами ObjectBox

 @Entity()
class Customer {
  int id;
  @Backlink('customer')
  final orders = ToMany<Order>();
}

@Entity()
class Order {
  int id;
  final customer = ToOne<Customer>();
}
 

Я бы сохранил родителя (клиента) с вложенными данными, возражающими (заказ), в 2 связанных полях

 Customer customer = domainData.toObjectBox; // but how to get the order out?
customer.orders.add(Order('Order 1'));  // shouldn't this be Order(1)?
final customerId = store.box<Customer>().put(customer);
 

Именно так я обычно реализую этот toObjectBox метод. Здесь вы видите, что это не работает, потому что мне пришлось бы разделить родителя и вложенного ребенка. Хотя я думаю, что мог бы добиться этого с помощью некоторых спагетти, мне интересно, есть ли разумный способ сделать это, так как я предполагаю, что это должно быть обычным шаблоном (хотя я не нашел никаких вопросов и ответов по этому поводу).

 @Entity()
Customer {
  int id;
  List<Order> orders;
  Customer({required this.id, required this.orders});
  
  CustomerObox toObjectBox() {
    return CustomerObox(
      id: id,
//      orders: orders.map((x) => x.toObjectBox()).toList()
    );
}
 

=== ОБНОВЛЕНИЕ =====================================

Тем временем я сам попытался создать структуру возврата, и теперь я нахожусь в процессе, чтобы заставить это работать.

 class Pair<T1, T2> {
  final T1 parent;
  final T2 child;
  Pair({required this.parent, required this.child});
}

@Entity()
class Customer {
  int id;
  List<Order> orders;
  Customer({required this.id, required this.orders});
      
  static Pair<CustomerObox, List<OrderObox>> toObjectBox(Customer cust) {
    Pair<CustomerObox, List<OrderObox>>(
        parent: CustomerObox(
                  id: cust.id,
                ),
        child: cust.orders.map((o) => o.toObjectBox()).toList()
    );
  }      
}
 

Комментарии:

1. Причины, по которым вы не можете/не хотите аннотировать свои доменные классы, @Entity() как описано в первом блоке кода? Это дало бы наилучшие результаты без каких-либо вручную написанных (==хрупких) преобразований…

2. Просто забыл напечатать это здесь. Поскольку мой реальный код усложнил бы выполнение, я адаптировал пример ObjectBox, но только в редакторе stackoverflow, а не в IDE. Я обновил код, поэтому я предполагаю, что все @Entity() должны присутствовать сейчас

Ответ №1:

Поэтому я реализовал toObjectBox , как показано в обновлении моего вопроса выше.

Внутри моей реализации локального источника данных (я использую слои: презентация > бизнес-логика (блок) >> домен (модели, контракты и т.д.) >>> репозиторий >>>> источник данных) Я реализовал следующие методы

 @override
  Future<void> storeCustomer(Customer customer) async {
    // Pair(T1 parent, T2 child) with T2 being List<OrderObox>
    final Pair customerObox = Customer.toObjectBox(customer);
    final CustomerObox customerParent = customerObox.parent;
    final List<OrderObox> customerChildren = customerObox.child;

    for (final child in customerChildren)
      customerParent.records.add(child);
    //  puts both, parent and children:
    final id = _sBox.put(customerParent);
  }
 
   @override
  Future<List<Customer>> getAllCustomers() async {
    final List<Customer> parents = [];
    final List<CustomerObox> parentsObox = await _sBox.getAll();
    for (final p in parentsObox) {
      final List<CustomerObox> childrenObox = p.records;
      parents.add(SessionJournalDto.fromObjectBox(p));
      for (final c in childrenObox)
        parents.last.records.add(Order.fromObjectBox(c));
    }
    return parents;

  }
 

Комментарии:

1. если у кого-то есть идея получше, дайте мне знать