You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

LiteDB:实例长期持有vs每次CRUD开闭,更新失效问题咨询

LiteDB更新失败问题分析与解决

我挺喜欢LiteDB,但确实社区支持不足这点很头疼,连论坛或Discord都没有,排查问题全靠自己试。先给你理清两种数据库使用方式的核心注意点,再解决你遇到的更新失败问题:

两种用法的核心原则

  • 长期保持数据库实例开启:这是LiteDB推荐的常规用法,它的连接是线程安全的,长期持有不会有性能问题,还能避免反复打开关闭连接的开销。
  • 每次CRUD操作开关实例:适合低频率操作的脚本场景,但必须注意:绝对不能持有using块外的数据库/集合实例,因为using块结束后,数据库资源会被释放,对应的实例会失效。

你的代码问题拆解

你第二段代码更新失败,核心有两个错误:

1. 非法使用已释放的集合实例

你在第二个using块外持有了recalledGames集合实例,当using块结束,内部的db对象被释放,recalledGames的内部状态也会失效。此时调用recalledGames.FindAll()属于非法操作,哪怕侥幸拿到对象,后续流程也会埋下隐患。正确的查询写法应该把查询逻辑放在using块内部:

Game firstGame;
using (var db = new LiteDatabase(ConnectionString))
{
    var recalledGames = db.GetCollection<Game>("games");
    firstGame = recalledGames.FindAll().First();
}

2. 更新时使用了错误的集合名

你最后一个using块里写的是db.GetCollection<Game>(),LiteDB默认会把类名Game作为集合名,但你之前插入数据用的是集合名"games"(复数)——相当于你在更新一个完全不同的空集合,自然不会有任何数据变化。必须指定和插入时一致的集合名:

using (var db = new LiteDatabase(ConnectionString))
{
    var games = db.GetCollection<Game>("games");
    games.Update(firstGame);
    // 注:LiteDB在using块结束时会自动提交变更,手动Commit除非是开启了显式事务,否则可以省略
}

修正后的完整代码

using (var db = new LiteDatabase(ConnectionString))
{
    var games = db.GetCollection<Poco.Game>("games");
    Poco.Game newGame = new Poco.Game() { Id = ObjectId.NewObjectId(), Name = "R-Type" };
    games.Insert(newGame);
}

Game firstGame;
using (var db = new LiteDatabase(ConnectionString))
{
    var recalledGames = db.GetCollection<Game>("games");
    firstGame = recalledGames.FindAll().First();
}

firstGame.Name = "BC's quest for tyres";

using (var db = new LiteDatabase(ConnectionString))
{
    var games = db.GetCollection<Game>("games");
    games.Update(firstGame);
}

补充说明:LiteDB的Update方法确实是根据主键(你的Id字段)匹配数据的,但前提是操作的是同一个集合,且主键值正确。

内容的提问来源于stack exchange,提问作者stigzler

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 23:17:23