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

.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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 05:15:23