sqlite 在我的Flutter项目中,SQLflite数据库中的数据未删除

vshtjzan  于 2023-02-09  发布在  SQLite
关注(0)|答案(1)|浏览(188)

所以我遇到了一个数据不能从我的数据库中删除的问题。它应该发生在一个可删除的小部件被刷走的时候。这是一个模型类:

class DateModel {
  //define schema
  int? id;
  final String dateText;

  DateModel({this.id, required this.dateText});

  //convert json data to DateModel instance
  factory DateModel.fromMap(Map<String, dynamic> json) {
    return DateModel(id: json["id"], dateText: json["dateText"]);
  }

  //convert DateModel instance to json 
  Map<String, dynamic> toMap() => {"id": id, "dateText": dateText};
}

下面是一些CRUD操作的定义。我得出的结论是,错误是因为我没有正确地存储插入时的id(在“add”函数中)。尽管我不确定我做得是否正确。

class DatabaseHelper {
  static Database? _db;

  //create singleton
  DatabaseHelper._constructor();
  static final DatabaseHelper instance = DatabaseHelper._constructor();

  Future<Database> get db async {
    return _db ??= await init_db("Date.db");
  }

  //create database when it doesn't exist
  Future<Database> init_db(String name) async {
    //locate database
    var databasePath = await getDatabasesPath();
    String path = join(databasePath, name);

    //open database and return
    return await openDatabase(path, version: 1, onCreate: _onCreate);
  }

  //Create date table
  Future _onCreate(Database db, int version) async {
    await db
        .execute("CREATE TABLE Dates (id INTEGER PRIMARY KEY, dateText TEXT)");
  }

  //add user input to table
  Future<int> add(DateModel dateModel) async {
    Database db = await instance.db;

    //store id of inserted date (generated by db.insert method)
    final id = await db.insert("Dates", dateModel.toMap());
    return dateModel.id = id;
  }

  //remove date from table
  Future<int> remove(int id) async {
    Database db = await instance.db;
    return await db.delete("Dates", where: "id = ?", whereArgs: [id]);
  }

  Future<List> getDates() async {
    Database db = await instance.db;
    final data = await db.rawQuery("SELECT dateText FROM Dates");
    if (data.isNotEmpty) {
      return data;
    } else {
      return [];
    }
  }
}

最后,这是删除操作应该发生的地方(在dismissible的onDismissed属性中):

Widget build(BuildContext context) {
    return Consumer<Date>(builder: (context, date, child) {
      return Scaffold(
        body: FutureBuilder(
          future: DatabaseHelper.instance.getDates(),
          builder: (context, AsyncSnapshot<List<dynamic>> snapshot) {
            if (!snapshot.hasData || snapshot.connectionState != ConnectionState.done) {
              return CircularProgressIndicator();
            }

            return ListView.builder(
                shrinkWrap: true,
                itemCount: snapshot.data!.length,
                itemBuilder: (context, index) {
                  return SlideTransition(
                    position:
                        Tween<Offset>(begin: Offset(1, 0), end: Offset(0, 0))
                            .animate(CurvedAnimation(
                                parent: _controller, curve: Curves.bounceIn)),
                    child: Dismissible(
                        key: UniqueKey(),
                        direction: DismissDirection.horizontal,
                        onDismissed: (direction) async {
                          final dateModel =
                              DateModel(dateText: date.dateList[index]);

                          //remove from list
                          date.dateList.removeAt(index);

                        //remove from database
                         await DatabaseHelper.instance.remove(dateModel.id!);
                        },
                        child: ListTile(title: Text(snapshot.data![index].toString()))),
                  );
                });
          },
        ),
      );
    });
  }

我得到一个错误,即我正在对一个空值进行空检查,我认为该空值是dateModel.id。
我试过用几种不同的方法在插入时存储id,没有什么变化。

8fq7wneg

8fq7wneg1#

这是因为你正试图做到这一点:对空值放置空检查运算符。
您将创建如下的dateModel:

final dateModel = DateModel(dateText: date.dateList[index]);

您没有为id传递任何值,因此id为空。
试试这样的方法:

Map<String, dynamic> dateJson = snapshot.data![index] as Map<String, dynamic>;
DateModel dateModel = DateModel.fromMap(dateJson);
date.dateList.removeAt(index);
await DatabaseHelper.instance.remove(dateModel.id);

PS:你不应该在你的DateModel类中使id可选,因为它应该总是被给定的。

相关问题