Flutter使用flutter_moor查询SQLite中创建30天内的最新钱包记录
你之前的写法问题在于将表的startDate字段自身作为区间判断的上下限,相当于执行startDate >= startDate AND startDate <= startDate + 30天的逻辑,对所有合法的日期值都恒成立,所以完全没有过滤效果。
正确实现代码如下,同时满足你要求的「创建时间距当前30天内」、「新月份不查上月记录」两个规则:
Stream<Wallet?> watchLatestCreatedWallet() { final now = DateTime.now(); // 30天前的时间点,用于过滤超过30天的记录 final thirtyDaysAgo = now.subtract(const Duration(days: 30)); // 当月第一天零点,用于过滤上月的记录 final firstDayOfCurrentMonth = DateTime(now.year, now.month, 1); final Stream<Wallet?> wallet = ( select(wallets) ..orderBy([ (wallet) => OrderingTerm( expression: wallet.startDate, mode: OrderingMode.desc ) ]) // 两个过滤条件同时生效 ..where((tbl) => tbl.startDate.isBiggerOrEqualValue(thirtyDaysAgo)) ..where((tbl) => tbl.startDate.isBiggerOrEqualValue(firstDayOfCurrentMonth)) ..limit(1) ) // 无符合条件记录时返回null,避免抛出异常 .watchSingleOrNull(); return wallet; }
补充说明:
- moor中带
Value/Values后缀的判断方法,接收的是Dart侧的常量参数,而非数据库字段引用,避免了原来的自引用问题。如果不需要同月份限制,只保留30天过滤的话,可以用isBetweenValues简化写法:..where((tbl) => tbl.startDate.isBetweenValues(thirtyDaysAgo, now)) - 若你的业务逻辑确定一定会有符合条件的记录,可以换回
watchSingle方法,返回值类型改为Wallet即可。
内容的提问来源于stack exchange,提问作者hesham shawky
相关产品推荐
相关产品推荐

