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

在Xamarin Android中获取Insert/UpdateAsync操作后的记录主键

解决Xamarin中SQLiteAsync获取操作后记录主键的问题

问题根源

你在SaveGame方法中直接调用Task.Result会导致线程死锁:同步线程阻塞等待异步任务完成,而异步任务又需要等待同步线程释放上下文,最终互相卡住,表现为await处挂起。

修正方案

1. 确保实体类主键配置正确

DBMatch的matchKey需要标记为自增主键,这样SQLite在插入时会自动生成主键并赋值给实体:

public class DBMatch
{
    [PrimaryKey, AutoIncrement]
    public int matchKey { get; set; }
    // 其他业务属性...
}

2. 全程使用异步调用,避免阻塞

把同步方法改为异步,用await替代Task.Result,消除死锁风险:

public class GameDatabase
{
    readonly SQLiteAsyncConnection database;

    // 构造函数(需初始化数据库连接)
    public GameDatabase(string dbPath)
    {
        database = new SQLiteAsyncConnection(dbPath);
        database.CreateTableAsync<DBMatch>().Wait();
    }

    // 改为异步方法,用await等待操作完成
    public async Task SaveGame(DBMatch dbMatch)
    {
        var updatedMatch = await SaveMatchAsync(dbMatch);
        _match.matchKey = updatedMatch.matchKey;
    }

    public async Task<DBMatch> SaveMatchAsync(DBMatch dbMatch)
    {
        if (dbMatch.matchKey != 0)
        {
            // 更新操作:主键已存在,直接更新后返回原对象
            await database.UpdateAsync(dbMatch);
        }
        else
        {
            // 插入操作:SQLite会自动将生成的主键写入dbMatch.matchKey
            await database.InsertAsync(dbMatch);
        }
        return dbMatch;
    }
}

关键说明

  • 异步方法调用必须全程使用await,禁止在同步代码中直接获取Task.Result或Task.Wait(),否则极易引发死锁。
  • SQLite的InsertAsync执行成功后,会自动把自增主键值赋值给实体对象的主键属性,插入后直接返回原对象就能拿到新生成的主键。
  • 更新操作本身不需要生成新主键,原对象的matchKey就是有效的主键,直接返回即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 06:35:45