Xamarin Android中ADO.NET SQLite表添加新列实现求助
给SQLite表添加新列的分步实现(基于你的YesDatabase类)
嘿,作为自学独立开发者,我太懂这种对着代码卡壳的感觉了!咱们结合你从Tasky示例里拿到的YesDatabase类,一步步搞定添加新列的操作,用到你提到的ALTER TABLE和PRAGMA table_info,还兼顾数据库版本升级的问题——毕竟咱们得保证老用户的数据不会丢对吧?
第一步:添加检查列是否存在的工具方法
先写个小方法,用PRAGMA table_info(表名)来判断目标列是否已经存在,避免重复执行ALTER语句报错。把这个方法加到你的YesDatabase类里:
private bool HasColumn(string tableName, string columnName) { lock (locker) { // 执行PRAGMA语句查询表结构 var query = connection.Query<TableColumn>($"PRAGMA table_info({tableName})"); // 检查是否有匹配的列名(忽略大小写兼容不同命名风格) return query.Any(c => c.Name.Equals(columnName, StringComparison.OrdinalIgnoreCase)); } } // 用来映射PRAGMA查询结果的辅助类 private class TableColumn { public string Name { get; set; } }
第二步:在数据库初始化时执行列添加逻辑
接下来,把添加新列的逻辑整合到你的YesDatabase构造函数里。比如咱们要给Tasky示例里的Tasks表,添加一个IsUrgent布尔类型的列:
public YesDatabase(string dbPath) { path = dbPath; bool exists = File.Exists(dbPath); connection = new SqliteConnection(dbPath); if (!exists) { // 首次创建数据库,直接建表 connection.CreateTable<Task>(); } else { // 数据库已存在,检查并添加新列 lock (locker) { // 检查Tasks表是否有IsUrgent列 if (!HasColumn("Tasks", "IsUrgent")) { // 执行ALTER TABLE添加列,设置默认值避免现有数据报错 connection.Execute("ALTER TABLE Tasks ADD COLUMN IsUrgent INTEGER DEFAULT 0"); } // 要是以后还要加其他列,直接在这里复制上面的检查+执行逻辑就行 } } }
关键注意点(踩过坑的经验分享)
- SQLite的ALTER限制:SQLite只允许用
ALTER TABLE添加新列,不能修改或删除现有列(除非用备份-重建-恢复的复杂流程,日常升级用添加列就够了)。 - 必须加默认值:给新列设置
DEFAULT值很重要,不然现有数据行的新列会是NULL,可能导致你的实体类映射报错(比如布尔类型不能为NULL)。 - 锁的必要性:别忘了用你已经定义的
locker对象加锁,避免多线程操作数据库时出现异常。 - 版本管理进阶:如果以后有更多结构变化,建议给数据库加版本号,比如读取
PRAGMA user_version,按版本号执行对应的迁移脚本,这样逻辑更清晰:
public YesDatabase(string dbPath) { path = dbPath; bool exists = File.Exists(dbPath); connection = new SqliteConnection(dbPath); if (!exists) { connection.CreateTable<Task>(); // 设置初始版本号 connection.Execute("PRAGMA user_version = 1"); } else { // 获取当前数据库版本 var currentVersion = connection.ExecuteScalar<int>("PRAGMA user_version"); lock (locker) { // 版本1升级到版本2:添加IsUrgent列 if (currentVersion < 2) { connection.Execute("ALTER TABLE Tasks ADD COLUMN IsUrgent INTEGER DEFAULT 0"); connection.Execute("PRAGMA user_version = 2"); } // 版本2升级到版本3:添加Notes列 if (currentVersion < 3) { connection.Execute("ALTER TABLE Tasks ADD COLUMN Notes TEXT"); connection.Execute("PRAGMA user_version = 3"); } } } }
这样不管以后加多少列,都能按版本逐步升级,不会搞混~
内容的提问来源于stack exchange,提问作者money
相关产品推荐
相关产品推荐

