#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. если у кого-то есть идея получше, дайте мне знать