Xamarin中SQLite执行DeleteAsync删除NoteModel时应用崩溃问题
问题描述
我是Xamarin与SQLite开发初学者,当前尝试为应用实现基于SQLite的NoteModel模型数据存储功能,新增数据流程运行正常,但执行模型删除操作时应用会直接崩溃。
相关实现代码如下:
1. NoteModel模型定义
public class NoteModel { [PrimaryKey, AutoIncrement] public int Id { get; set; } public string Name { get; set; } public string Text { get; set; } }
2. SQLite操作封装类SQLiteDataStore实现
public class SQLiteDataStore { public SQLiteAsyncConnection database; public SQLiteDataStore(string dbPath) { database = new SQLiteAsyncConnection(dbPath); database.CreateTableAsync<NoteModel>(); } public Task<List<NoteModel>> GetNotesAsync() { return database.Table<NoteModel>().ToListAsync(); } public Task<int> SaveNoteAsync(NoteModel model) { return database.InsertAsync(model); } public Task<int> DeleteNoteAsync(NoteModel model) { return database.DeleteAsync<NoteModel>(model); } }
3. ViewModel层SQLiteDataStore单例初始化逻辑
public static SQLiteDataStore datastore; public static SQLiteDataStore DataStore { get { if (datastore == null) { datastore = new SQLiteDataStore(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "NoteData.db")); } return datastore; } }
删除操作触发逻辑
private async void OnNoteSelected(NoteModel note) { await DataStore.DeleteNoteAsync(note); }
问题具体表现
新增NoteModel数据无任何异常,但代码执行到return database.DeleteAsync<NoteModel>(model);这一行时应用立刻崩溃,调试确认传入的待删除NoteModel实例参数状态正常:
问题原因
核心问题出在两个地方:
- 构造函数中调用
database.CreateTableAsync<NoteModel>();没有加await,属于典型的fire-and-forget异步调用,表创建操作没有完成就可能触发后续CRUD操作。新增操作能成功是因为插入操作执行时表刚好已经创建完成,但删除操作触发时存在竞态条件,数据库连接状态异常直接崩溃。 - 异步事件处理
OnNoteSelected没有做异常捕获,底层SQLite抛出的异常没有被处理,直接导致应用闪退。
修复方案
- 修正SQLite初始化逻辑,确保表创建完成后再执行数据库操作,不要在构造函数里跑无等待的异步任务,新增异步初始化判断:
public class SQLiteDataStore { public SQLiteAsyncConnection database; private bool _isInitialized = false; public SQLiteDataStore(string dbPath) { database = new SQLiteAsyncConnection(dbPath); } private async Task InitializeAsync() { if (!_isInitialized) { await database.CreateTableAsync<NoteModel>(); _isInitialized = true; } } public async Task<List<NoteModel>> GetNotesAsync() { await InitializeAsync(); return await database.Table<NoteModel>().ToListAsync(); } public async Task<int> SaveNoteAsync(NoteModel model) { await InitializeAsync(); return await database.InsertAsync(model); } public async Task<int> DeleteNoteAsync(NoteModel model) { await InitializeAsync(); return await database.DeleteAsync(model); } }
- 给删除操作的事件处理加上异常捕获,避免未处理异常直接闪退:
private async void OnNoteSelected(NoteModel note) { try { await DataStore.DeleteNoteAsync(note); // 可在此处添加删除成功后的列表刷新逻辑 } catch (Exception ex) { // 调试阶段可输出异常信息,正式环境可加错误提示弹窗 Console.WriteLine($"删除笔记失败:{ex.Message}"); } }
额外说明:如果传入的
NoteModel对象是页面绑定的副本、和数据库查询出来的对象不是同一个引用,也可以直接传主键Id删除,写法为await database.DeleteAsync<NoteModel>(note.Id);,兼容性更好。
内容的提问来源于stack exchange,提问作者Kostas Soulios
相关产品推荐
相关产品推荐

