Как моделировать и загружать данные из связанных таблиц, используя Sqflite - PullRequest
0 голосов
/ 22 апреля 2020

У меня есть две связанные таблицы с внешним ключом, объявленным в моей схеме:


CREATE TABLE Collection(
    id INTEGER PRIMARY KEY,
    name TEXT,
    start_date INT
);

CREATE TABLE Item (
    id INTEGER PRIMARY KEY,
    collection_id INTEGER,
    name TEXT,
    FOREIGN KEY (collection_id) REFERENCES Collection(id)
);

И у меня есть модели этих таблиц в Dart:

class Collection {
  int id;
  String name;
  DateTime startDate;
  List<Item> items;

  Collection({
    this.id,
    this.name = '',
    this.startDate,
    this.items,
  });

  factory Collection.fromJson(Map<String, dynamic> json) => Collection(
    id            : json["id"],
    name          : json["name"],
    startDate     : DateTime.fromMillisecondsSinceEpoch(json["start_date"]),
    items         : List<Item>.from(json["items"].map((x) => Item.fromJson(x))),
  );

  Map<String, dynamic> toJson() => {
    "id"            : id,
    "name"          : name,
    "start_date"    : startDate.millisecondsSinceEpoch,
    "items"         : List<dynamic>.from(items.map((x) => x.toJson())),
  };


class Item {
  int id;
  int collection_id;
  String name;

  Item({
    this.id,
    this.collection_id,
    this.name = '',
  });

  factory Item.fromJson(Map<String, dynamic> json) => Item(
    id            : json["id"],
    collection_id : json["collection_id"],
    name          : json["name"],
  );

  Map<String, dynamic> toJson() => {
    "id"            : id,
    "collection_id" : collection_id,
    "name"          : name,
  };

Я использую Поставщик БД для извлечения данных из базы данных, но я не знаю, как получить данные из основной таблицы и связанных с ней:

final response = await db.query('Collection', where: 'status = ?', whereArgs: ['in progress']);
return response.isNotEmpty ? Collection.fromJson(response.first) : null;

, поэтому я получаю нулевое исключение при попытке создать экземпляр Collection без данные в поле элементов.

Знаете ли вы, как извлечь данные из основной таблицы и связанных с ней в одном запросе?

Конечно, я могу сделать второй запрос загрузить его, но идея заключается в том, чтобы сделать это в одном запросе.

1 Ответ

0 голосов
/ 30 апреля 2020

здесь решение с Left Join rawQuery, и тогда вы можете groupBy свою карту и создать новую карту, такую ​​же, как ваша модель

Future<List<Collection>> getcoll() async {
    var dbClient = await db;

    // rawQuery with Left Join over 2 Tables
    String query = 'SELECT C.id AS collection_id, ' +
        ' C.name AS cname, ' +
        ' C.start_date as start_date, ' +
        ' Item.id as id, ' +
        ' Item.name as name ' +
        ' FROM Collection C' +
        ' LEFT JOIN Item ON Item.collection_id = C.id';
    List<Map> result = await dbClient.rawQuery(query);

    // new Map groupBy collection_id
    var newMap = groupBy(result, (obj) => obj['collection_id']);

    // create new Map    
    List<Map<String, dynamic>> newMap2 = new List();
    newMap.forEach((f, values) {

      // add new Map the same as your Model
      newMap2.add({
        "id": f,
        "name": values[0]["cname"],  // use first value in list it is always the same
        "start_date": values[0]["start_date"],
        "items": values // all values from the item Table +Collection Fields but they are nut used
      });

    });

    // toList function to your List Model
    List<Collection> r_Collection = newMap2.map((i) => Collection.fromJson(i)).toList();

    return r_Collection;

  }
...