skip to Main Content

I have these 2 entities in objectbox:

@Entity()
class Account {
  @Id()
  int id = 0;
}


@Entity()
class Transaction {

  @Id()
  int id = 0;

  final fromAccount = ToOne<Account>();
  final toAccount = ToOne<Account>();
}

I need to query all transactions from or to a particular account. I’m unable to figure out the query. Tried this but it doesn’t work:

Future<List<Transaction>> getAllTransactionsForAccount(int accountId) {
    QueryBuilder<Transaction> builder = box.query();
    builder.link(
        Transaction_.toAccount, Account_.id.equals(accountId));
    builder.link(
        Transaction_.fromAccount, Account_.id.equals(accountId));
    Query<Transaction> q = builder.build();
    return q.findAsync();
  }

If I remove one of the builder.link for fromAccount or toAccount, it works, but I need both, not just one.
Could someone help please ?

2

Answers


  1. the code you have given will allow you to apply one condition at a time, and to query all transactions either from or to a particular ObjectBox u can combine two conditions using or operator,

    Future<List<Transaction>> getAllTransactionsForAccount(int accountId) async {
      // Query for transactions where toAccount equals the given accountId
      QueryBuilder<Transaction> toAccountBuilder = box.query()
        ..link(Transaction_.toAccount, Account_.id.equals(accountId));
      Query<Transaction> toAccountQuery = toAccountBuilder.build();
    
      // Query for transactions where fromAccount equals the given accountId
      QueryBuilder<Transaction> fromAccountBuilder = box.query()
        ..link(Transaction_.fromAccount, Account_.id.equals(accountId));
      Query<Transaction> fromAccountQuery = fromAccountBuilder.build();
    
      // Fetch results for both queries
      List<Transaction> toAccountTransactions = await toAccountQuery.findAsync();
      List<Transaction> fromAccountTransactions = await fromAccountQuery.findAsync();
    
      // Combine results
      List<Transaction> allTransactions = []
        ..addAll(toAccountTransactions)
        ..addAll(fromAccountTransactions);
    
      // Optionally, remove duplicates if needed
      final transactionSet = <int>{};
      final uniqueTransactions = allTransactions.where((transaction) {
        return transactionSet.add(transaction.id);
      }).toList();
    
      return uniqueTransactions;
    }
    

    this would work

    Login or Signup to reply.
  2. link method in ObjectBox’s QueryBuilder works as an "AND" operator, not an "OR". This means that your current query is looking for transactions where both fromAccount and toAccount are the same, which is not what you want.

    Future<List<Transaction>> getAllTransactionsForAccount(int accountId) async {
      // Query for transactions where fromAccount matches the given accountId
      final fromAccountQuery = box.query(Transaction_.fromAccount.targetId.equals(accountId)).build();
      final fromAccountTransactions = await fromAccountQuery.find();
    
      // Query for transactions where toAccount matches the given accountId
      final toAccountQuery = box.query(Transaction_.toAccount.targetId.equals(accountId)).build();
      final toAccountTransactions = await toAccountQuery.find();
    
      // Combine the results of the two queries
      final allTransactions = {...fromAccountTransactions, ...toAccountTransactions};
    
      return allTransactions.toList();
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search