Flutter版ObjectBox如何实现两个属性的对比查询?
解决Dart版ObjectBox属性对比查询的方案
一、属性直接对比(如firstNumber > secondNumber)
Dart版ObjectBox目前不支持直接在查询中对比同一实体的两个属性,也没有Java版的查询过滤器功能。以下是两种高效替代方案:
1. 计算派生属性(推荐)
在实体类中新增一个派生属性,在对象存入或更新时预先计算值,将属性对比的逻辑提前完成:
@Entity() class ObjectA { int id; int firstNumber; int secondNumber; bool isFirstGreater; // 派生属性,存储firstNumber>secondNumber的结果 ObjectA({ required this.id, required this.firstNumber, required this.secondNumber, }) : isFirstGreater = firstNumber > secondNumber; // 更新属性时同步更新派生属性 void updateNumbers(int newFirst, int newSecond) { firstNumber = newFirst; secondNumber = newSecond; isFirstGreater = firstNumber > secondNumber; } }
后续查询直接通过派生属性过滤,完全利用ObjectBox的索引能力,性能最优:
final results = boxA.query(ObjectA_.isFirstGreater.equals(true)).build().find();
2. 内存过滤(小数据量适用)
如果数据规模较小,可先查询全量数据再在内存中过滤:
final allObjects = boxA.getAll(); final filtered = allObjects.where((obj) => obj.firstNumber > obj.secondNumber).toList();
注意:数据量过万时会明显影响性能,不推荐大规模使用。
二、关联查询中匹配父对象属性(如子对象名称匹配父对象favoriteChild)
这类跨关联实体的属性对比,同样可以用派生属性的思路解决:
1. 父实体新增匹配标记属性
在父实体中新增hasFavoriteChild属性,在关联子对象或更新favoriteChild时,提前检查是否存在匹配的子对象并更新标记:
@Entity() class ParentObject { int id; String? favoriteChild; bool hasFavoriteChild; // 派生属性,标记是否存在匹配的子对象 final children = ToMany<ChildObject>(); ParentObject({required this.id, this.favoriteChild}) : hasFavoriteChild = false; // 更新匹配状态的方法 void updateFavoriteChildMatch() { if (favoriteChild == null) { hasFavoriteChild = false; return; } hasFavoriteChild = children.any((child) => child.name == favoriteChild); } }
存入或更新父对象前调用updateFavoriteChildMatch(),查询时直接过滤:
final results = parentBox.query(ParentObject_.hasFavoriteChild.equals(true)).build().find();
2. 批量预计算(针对已有数据)
如果是已有大量数据需要处理,可批量查询父对象并更新派生属性:
final allParents = parentBox.getAll(); for (var parent in allParents) { parent.updateFavoriteChildMatch(); } parentBox.putMany(allParents);
内容的提问来源于stack exchange,提问作者Mark Weinhold
相关产品推荐
相关产品推荐

