在Xamarin/sqlite-net-pcl中重置SQLite自增序列无效,求解决方案
我来帮你捋捋这个问题——你遇到的情况在sqlite-net-pcl里其实挺常见的,咱们一步步排查原因和解决办法:
1. 先确认实体类的自增主键配置是否正确
首先得确保你的mytable实体类确实使用了sqlite的自增rowid机制,也就是给主键字段加上了[PrimaryKey, AutoIncrement]属性。如果没有这个配置,sqlite根本不会在sqlite_sequence表中生成对应记录,你的更新/删除操作自然无效。举个正确的实体类例子:
public class mytable { [PrimaryKey, AutoIncrement] public int Id { get; set; } // 其他业务字段... }
2. 检查事务提交问题
sqlite-net-pcl的DeleteAll<T>()方法默认会开启事务,如果你紧接着执行Execute()操作时,前一个事务还没提交,可能会因为事务隔离的问题,导致对sqlite_sequence的修改没有生效。建议把两个操作放到同一个事务里执行,确保原子性:
using (var transaction = db.BeginTransaction()) { try { db.DeleteAll<mytable>(); db.Execute("update sqlite_sequence set seq = 0 where name = 'mytable';"); transaction.Commit(); } catch (Exception ex) { transaction.Rollback(); // 这里可以添加异常日志或处理逻辑 } }
3. 排查表名大小写匹配问题
sqlite默认对表名大小写不敏感,但sqlite_sequence里存储的是表创建时的精确大小写。比如你的实体类对应的表名实际是MyTable(首字母大写),但你SQL语句里写的是'mytable',就会匹配不到目标记录。可以先查询sqlite_sequence表,确认真实的表名:
// 先定义一个对应sqlite_sequence结构的辅助类 public class SqliteSequenceEntry { public string name { get; set; } public int seq { get; set; } } // 查询所有序列记录 var sequenceEntries = db.Query<SqliteSequenceEntry>("SELECT * FROM sqlite_sequence;"); foreach (var entry in sequenceEntries) { Console.WriteLine($"表名: {entry.name}, 当前自增序列值: {entry.seq}"); }
拿到真实表名后,把SQL语句里的表名改成完全一致的即可。
4. 排除特殊表类型的可能
如果你的表是WITHOUT ROWID类型(不过sqlite-net-pcl默认不会创建这种表),那sqlite本身不会为该表维护rowid和自增序列,这种情况下sqlite_sequence里也不会有对应记录,自然无法重置。你可以通过查询表结构确认:
PRAGMA table_info(mytable);
如果结果里没有rowid相关字段,且表创建语句包含WITHOUT ROWID,那就是这种情况了。
一般来说,排查完上面几个点,尤其是表名大小写和事务的问题,就能解决无法重置自增rowid的情况啦。
内容的提问来源于stack exchange,提问作者Karen Cate

