0

我希望你一切都好。

我的应用程序有一点问题,我正在为数据库使用Drift包,我试图弄清楚如何在我的数据库中插入一个枚举列表。

我有一个表 Etablissements,其中包含一个列,该列将是一个枚举列表,代表该机构中可用的不同级别:

@DataClassName('Establishment')
class Establishments extends Table {
  TextColumn get id => text().clientDefault(() => generateId())();

  BoolColumn get isConfigured => boolean().withDefault(const Constant(false))();

  TextColumn get slogan => text().nullable()();

  TextColumn get contact => text().references(Contacts, #id)();

  TextColumn get name => text()();

  TextColumn get admin => text()();

  TextColumn get cycles => text().map(const CyclesListConverter())();

  @override
  Set<Column>? get primaryKey => {id};
}

并且基于插件的文档,使用类型转换器将复杂数据存储在列中,我能够创建我的转换器,它允许我将枚举列表序列化为 JSON 字符串,以便能够更轻松地存储列中的枚举列表(反之,将 JSON 字符串转换回枚举列表

class CyclesListConverter extends TypeConverter<List<Cycles>, String> {
  const CyclesListConverter();

  @override
  List<Cycles>? mapToDart(String? fromDb) {
    if (fromDb == null) return null;

    final data = json.decode(fromDb);

    final studyCycles = data['body'];

    return studyCycles;
  }

  @override
  String? mapToSql(List<Cycles>? value) {
    if (value == null) return null;

    return json.encode(value);
  }
}

但是在我的程序执行时,当我尝试插入

我从 Drift 包中收到以下错误

[log] Converting object to an encodable object failed: Instance of 'Cycles'

您能帮我解决问题并让我了解错误的原因以及我做错了什么吗?

我的枚举

enum Cycles { elementary, primary, secondary, secondaryTechnique }
4

1 回答 1

0

经过一段时间的反思,这就是我能够解决问题的方法。我从枚举中提取值以将其作为字符串存储在数据库中。然后将该值添加到字符串列表中。然后这个列表用 JSON 编码

String? mapToSql(List<Cycles>? value) {
    if (value == null) return null;
    var data = <String>[];

    for (var v in value) {
      final strCycle = v.displayName();
      data.add(strCycle);
    }

    return json.encode(data);
  }

为了在 Dart 中找到枚举,我对前一个进行了逆运算

我检索字符串列表(代表我的枚举)。对于此列表的每个字符串,我将其转换回相应的枚举

List<Cycles>? mapToDart(String? fromDb) {
    if (fromDb == null) return null;

    var studyCycles = <Cycles>[];

    final jsonData = json.decode(fromDb);

    final strData = jsonData['body'] as List<String>;

    for (var string in strData) {
      final enumCycle = Cycles.values.firstWhere((element) => element.toString() == 'Cycles.$string');
      studyCycles.add(enumCycle);
    }

    return studyCycles;
  }
于 2021-12-24T18:30:34.740 回答