在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
相关产品推荐
相关产品推荐

