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

.NET Maui SQLite数据库问题、存储路径及架构优化咨询

.NET Maui习惯追踪应用数据库与代码优化解决方案

一、SQLite数据库文件查看与更新问题

  • 你遇到的DB Browser文件未更新,大概率是因为打开的是本地旧拷贝,而非模拟器中实时的数据库文件。解决方法:
    1. 使用Visual Studio的Device File Explorer(路径:View > Other Windows > Device File Explorer),找到Android模拟器中的路径:data/data/[你的应用包名]/files/database.db3,右键选择"Save As"导出最新文件到本地,再用DB Browser打开。
    2. 或用ADB命令拉取文件:
      adb pull /data/data/com.yourcompany.yourapp/files/database.db3 C:\LocalPath\database.db3
      
    操作后就能看到实时更新的数据库内容。

二、将数据库保存到应用根目录(外部存储)

可以实现,但需明确安全风险:Android外部存储的文件可能被其他应用访问、系统清理时被删除,且不符合平台隐私规范;iOS沙箱机制限制严格,无法直接保存到应用外部根目录。

修改Constants文件的DatabasePath实现(仅Android适用):

using System;
using System.IO;
using Android.OS; // 需要添加Android平台引用

namespace App.Data
{
    public static class Constants
    {
        public const string DatabaseFilename = "database.db3";

        public const SQLite.SQLiteOpenFlags Flags =
            SQLite.SQLiteOpenFlags.ReadWrite |
            SQLite.SQLiteOpenFlags.Create |
            SQLite.SQLiteOpenFlags.SharedCache;

        public static string DatabasePath
        {
            get
            {
                // Android外部存储公共目录(例如下载目录)
                string externalPath = Environment.GetExternalStoragePublicDirectory(Environment.DirectoryDownloads).AbsolutePath;
                return Path.Combine(externalPath, DatabaseFilename);
            }
        }
    }
}

注意:需在AndroidManifest.xml中添加权限:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

Android 10及以上还需在Application标签添加android:requestLegacyExternalStorage="true"。

三、独立Web API连接示例代码

用HttpClient封装基础API请求,示例如下:

using System.Net.Http;
using System.Net.Http.Json;
using System.Threading.Tasks;

namespace App.Services
{
    public class ApiService
    {
        private readonly HttpClient _httpClient;

        public ApiService()
        {
            _httpClient = new HttpClient
            {
                BaseAddress = new Uri("https://your-api-url.com/")
            };
        }

        // 登录请求示例
        public async Task<bool> LoginAsync(string username, string password)
        {
            var loginRequest = new { Username = username, Password = password };
            var response = await _httpClient.PostAsJsonAsync("api/auth/login", loginRequest);
            
            if (response.IsSuccessStatusCode)
            {
                var token = await response.Content.ReadAsStringAsync();
                // 保存token到SecureStorage
                await SecureStorage.SetAsync("auth_token", token);
                return true;
            }
            return false;
        }

        // 获取用户习惯示例
        public async Task<List<Habit>> GetUserHabitsAsync()
        {
            var token = await SecureStorage.GetAsync("auth_token");
            _httpClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token);
            
            return await _httpClient.GetFromJsonAsync<List<Habit>>("api/habits");
        }
    }
}

使用时在MauiProgram.cs注册为单例:

builder.Services.AddSingleton<ApiService>();

四、User与Habit表关联的登录方案优化

当前用关联表实现登录是本地应用的合理方案,但可从以下几点优化:

  1. 密码加密存储:绝对不要明文存储密码,用BCrypt或PBKDF2加盐哈希:
    // 注册时加密密码
    string hashedPassword = BCrypt.Net.BCrypt.HashPassword(password);
    // 登录时验证
    bool isPasswordValid = BCrypt.Net.BCrypt.Verify(inputPassword, storedHashedPassword);
    
  2. 数据库约束:给User表的Username添加唯一索引,避免重复注册;Habit表的UserId设为外键,关联User表的Id,确保数据完整性。
  3. 异步操作:所有数据库操作改用SQLite-net的异步API,避免阻塞UI线程:
    await db.InsertAsync(new User { Username = username, PasswordHash = hashedPassword });
    
  4. 扩展兼容性:若未来要迁移到云端,可将本地登录逻辑抽象为接口,方便切换到API验证。

五、Constants代码优化建议

针对你现有代码,可做以下调整:

  1. 增加数据库初始化检查:添加静态方法确保数据库文件存在并创建表:
    public static async Task InitializeDatabaseAsync()
    {
        using var db = new SQLiteAsyncConnection(DatabasePath, Flags);
        await db.CreateTableAsync<User>();
        await db.CreateTableAsync<Habit>();
    }
    
    在App.xaml.cs的OnStart方法中调用:await Constants.InitializeDatabaseAsync();
  2. Flags注释优化:明确SharedCache的适用场景,若应用为单线程操作数据库,可考虑移除SharedCache,避免潜在并发问题。
  3. 命名规范:DatabaseFilename可改为DbFilename更简洁,符合.NET命名习惯。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 14:56:14