0

假设我有 2 个简单的表UsersOrders

  • Users有列Id

  • Orders有列IdUserId

如何使用 moor_flutter 轻松获取用户的所有订单并将其作为以下模型的流返回?

class UserModel {
  final String id;
  final List<OrderModel> orderModels;

  UserModel(this.id, this.orders);
}

class OrderModel {
  final String id;

  OrderModel(this.id);
}

是官方文档,但未涵盖此用例。

EFCore 和 C# 的等效调用是:

public async Task<IEnumerable<UserModel>> GetUserOrders(String userId)
{
    return await _db.Users
        .Include(user  => user.Orders)
        .Where(user => user.Id == userId)
        .Select(user => new UserModel
        {
            Id = user.Id,
            OrderModels = user.Orders.Select(order => new OrderModel
            {
                Id = null,
            }).ToList()
        })
    .ToListAsync();
}
4

2 回答 2

1

我最近遇到了同样的问题。根据文档中给定的示例,我对使用 Joins 感到困惑。

我所做的是:

创建的类(仅在数据库文件中。请参见下面的示例)有两个要加入(组合)的对象。我在一类数据库中编写了查询。

您将通过示例更好地理解:

@UseMoor(
  tables: [OfflineProductMasters, OfflineProductWiseStocks],
)
class MyDatabase extends _$MyDatabase {
  // we tell the database where to store the data with this constructor
  MyDatabase() : super(_openConnection());

  // you should bump this number whenever you change or add a table definition. Migrations
  // are covered later in this readme.

  @override
  int get schemaVersion => 1;

  Future<List<ProductWithStock>> getProductWiseStock(String searchString, int mappingOfflineSalesTypeId) async {
    try {
      final rows = await (select(offlineProductMasters).join([innerJoin(offlineProductWiseStocks, offlineProductMasters.itemId.equalsExp(offlineProductWiseStocks.itemId))])
        ..where(offlineProductWiseStocks.salesTypeId.equals(mappingOfflineSalesTypeId) & offlineProductMasters.productName.like('$searchString%'))
        ..limit(50)
      ).get();
      return rows.map((row) {
        return ProductWithStock(
          row.readTable(offlineProductMasters),
          row.readTableOrNull(offlineProductWiseStocks),
        );
      }).toList();
    }catch(exception){
      print(exception);
      return Future.value([]);
    }
  }
}

class ProductWithStock {
  final OfflineProductMaster offlineProductMaster;

  final OfflineProductWiseStock? productWithStock;

  ProductWithStock(this.offlineProductMaster, this.productWithStock);
}

现在您已经了解了如何使用这种类型的查询的结构。希望您会以这种方式编写查询。

不知道你解决了没有。如果解决了,请发布答案,以便其他人获得帮助。

谢谢你。

于 2021-07-24T12:55:28.703 回答
0

这感觉像是一个 hacky 解决方法,但我最终做的是我创建了 2 个名为HabitWithLogsand的类HabitModel。我将查询结果放入HabitWithLogs实例中,然后将它们分组到HabitModel实例中。

数据类:

class HabitWithLog {
  final Habit habit;
  final HabitLog? habitLog;

  HabitWithLog({required this.habit, required this.habitLog}) : assert(habitLog == null || habitLog.habitId == habit.id);
}

class HabitModel {
  final Habit habit;
  final List<HabitLog> habitLogs;

  HabitModel({required this.habit, required this.habitLogs});
}

道法:

Future<List<HabitModel>> getAllHabits() async {
  // Get habits and order
  final query0 = (_db.select(_db.habits)..orderBy([(t) => OrderingTerm(expression: t.order, mode: OrderingMode.asc)]));

  // Join with habit logs
  final query1 = query0.join([
    leftOuterJoin(_db.habitLogs, _db.habitLogs.habitId.equalsExp(_db.habits.id)),
  ]);

  // Naive way that return the same habit multiple times
  final hwlList = query1.map((rows) => HabitWithLog(
        habit: rows.readTable(_db.habits),
        habitLog: rows.readTableOrNull(_db.habitLogs),
      ));

  // Group hwlList by habits
  final groups = (await hwlList.get()).groupListsBy((hwl) => hwl.habit);

  // Map grouping
  return groups.entries
      .map((group) => HabitModel(
            habit: group.key,
            habitLogs: (group.value[0].habitLog == null) ? List<HabitLog>.empty() : group.value.map((hwl) => hwl.habitLog!).toList(),
          ))
      .toList();
}

映射流感觉很糟糕,不应该是实现这一点的唯一方法。

于 2021-07-27T20:12:21.930 回答