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

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实例参数状态正常:
待删除的NoteModel实例


问题原因

核心问题出在两个地方:

  • 构造函数中调用database.CreateTableAsync<NoteModel>();没有加await,属于典型的fire-and-forget异步调用,表创建操作没有完成就可能触发后续CRUD操作。新增操作能成功是因为插入操作执行时表刚好已经创建完成,但删除操作触发时存在竞态条件,数据库连接状态异常直接崩溃。
  • 异步事件处理OnNoteSelected没有做异常捕获,底层SQLite抛出的异常没有被处理,直接导致应用闪退。

修复方案
  1. 修正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);
    }
}
  1. 给删除操作的事件处理加上异常捕获,避免未处理异常直接闪退:
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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 11:27:17