.NET MAUI应用更新时SQLite数据库是否会被清除?
问题解答
1. 商店更新后用户数据会丢失吗?
不会。你当前Debug编译时数据丢失,是因为Debug模式下每次部署都会清空应用的安装目录(默认数据库存储位置也会被覆盖)。但发布到应用商店的正式版,用户更新应用时,Android/iOS系统会保留应用的私有数据目录(每个应用专属的独立存储区域,用于存放用户生成的数据)——只要数据库文件存放在这个目录里,更新后数据不会丢失。
不过你的现有代码存在路径隐患:直接用dba.db作为文件名,数据库可能会被存在应用的安装目录(而非私有数据目录),如果是这种情况,更新时就有被覆盖的风险,所以第一步要修正存储路径。
2. 数据安全保障与备份恢复方案
第一步:修正数据库存储路径
在.NET MAUI中,使用FileSystem.AppDataDirectory获取平台专属的私有应用数据目录,这个目录在应用更新、卸载重装(部分平台)时会被保留。修改你的代码如下:
using Microsoft.Data.Sqlite; using System.IO; public static class SQLConn { private static readonly string DBName = "dba.db"; // 拼接私有数据目录与数据库文件名,确保数据持久化 private static readonly string DBPath = Path.Combine(FileSystem.AppDataDirectory, DBName); private static readonly string ConnectionString = $"Data Source={DBPath};"; public static void CreateDatabase() { string[] databasesToCreate = new string[] { "CREATE TABLE IF NOT EXISTS \"car_list\" ( \"car_id\" INTEGER UNIQUE, \"car_manufacturer\" TEXT NOT NULL, \"license_plate\" TEXT NOT NULL UNIQUE, \"date_purchase\" TEXT, \"price_purchase\" REAL, \"using_km\" INTEGER NOT NULL, \"km_purchase\" INTEGER, PRIMARY KEY(\"car_id\" AUTOINCREMENT) )", "CREATE TABLE IF NOT EXISTS \"user\" ( \"user_id\" INTEGER UNIQUE, \"user_name\" TEXT UNIQUE, \"password\" TEXT, PRIMARY KEY(\"user_id\" AUTOINCREMENT) )", }; using (var conn = new SqliteConnection(ConnectionString)) { conn.Open(); foreach (string createCommand in databasesToCreate) { if (!string.IsNullOrWhiteSpace(createCommand)) { using (var command = new SqliteCommand(createCommand, conn)) { command.ExecuteNonQuery(); } } } conn.Close(); } } }
第二步:备份与恢复机制
即使路径正确,极端情况(如更新时系统异常、数据库损坏)仍可能导致数据丢失,需添加备份逻辑:
备份逻辑
可以实现两种备份方式:
- 自动备份:用户退出应用或每周定时备份,将数据库复制到外部存储(Android SD卡、iOS文件应用可访问区域)
- 手动备份:给用户提供手动触发备份的按钮
备份代码示例:
public static void BackupDatabase() { // 先申请对应平台的外部存储权限(Android需READ_MEDIA_IMAGES/WRITE_EXTERNAL_STORAGE,iOS需开启文件共享权限) string backupDir = Path.Combine(FileSystem.Current.GetExternalStoragePublicDirectory(ExternalStorageDirectory.Documents).FullName, "MyAppBackups"); Directory.CreateDirectory(backupDir); // 用时间戳命名备份文件,避免覆盖 string backupPath = Path.Combine(backupDir, $"dba_backup_{DateTime.Now:yyyyMMddHHmmss}.db"); File.Copy(DBPath, backupPath, overwrite: true); }
恢复逻辑
给用户提供恢复入口,选择备份文件覆盖当前数据库:
public static void RestoreDatabase(string backupFilePath) { if (!File.Exists(backupFilePath)) return; // 先关闭所有数据库连接,避免文件被占用 using (var conn = new SqliteConnection(ConnectionString)) { conn.Open(); conn.Close(); } // 覆盖当前数据库文件 File.Copy(backupFilePath, DBPath, overwrite: true); }
第三步:数据库结构迁移
如果后续更新需要修改表结构(如新增字段),绝对不能删除重建表,要使用ALTER TABLE语句执行增量变更,避免丢失用户数据。例如给car_list新增car_color字段:
ALTER TABLE car_list ADD COLUMN car_color TEXT;
可以维护一个数据库版本号(存在单独的配置表或SQLite的user_version),每次启动应用时检查版本,执行对应版本的迁移脚本。
内容的提问来源于stack exchange,提问作者Raphael Frei
相关产品推荐
相关产品推荐

