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

MAUI(.NET8) Android端使用本地SQLite数据库报错求助

解决方案

核心问题分析

Windows端正常但Android端找不到表,本质是数据库文件未正确复制到Android应用的可读写私有目录:嵌入式资源存放在APK的只读区域,SQLite无法直接读写;同时AppDomain.CurrentDomain.BaseDirectory在Android环境下的路径指向与预期不符,导致连接到空文件或不存在的文件。

具体解决步骤

1. 配置数据库文件的项目属性

选中项目中的psyonicru_localdb.sqlite文件,在属性面板设置:

  • 生成操作:Embedded Resource
  • 复制到输出目录:如果较新则复制

2. 添加数据库文件复制逻辑

在初始化数据库前,将嵌入式资源复制到Android应用的可读写私有目录(使用MAUI官方FileSystem API获取正确路径)。修改你的WithDatabase方法:

using System.Reflection;
using Microsoft.Maui.Storage;

public static IServiceCollection WithDatabase(this IServiceCollection builderServices, IConfiguration builderConfiguration)
{
    // 1. 确定目标数据库路径
    var dbFileName = "psyonicru_localdb.sqlite";
    var targetDbPath = Path.Combine(FileSystem.AppDataDirectory, dbFileName);

    // 2. 从嵌入式资源复制数据库文件(仅当目标文件不存在或原文件更新时执行)
    if (!File.Exists(targetDbPath) || NeedUpdateDb(targetDbPath))
    {
        var assembly = Assembly.GetExecutingAssembly();
        // 注意:资源名称格式为「项目命名空间.文件所在目录.文件名」,比如项目命名空间是CBT.Maui.Blazor、文件在Files目录下,则为CBT.Maui.Blazor.Files.psyonicru_localdb.sqlite
        var resourceName = "YourProjectNamespace.Files.psyonicru_localdb.sqlite";
        
        using var resourceStream = assembly.GetManifestResourceStream(resourceName);
        using var fileStream = new FileStream(targetDbPath, FileMode.Create);
        resourceStream.CopyTo(fileStream);
    }

    // 3. 构建正确的连接字符串
    var singleConnectionString = $"Data Source={targetDbPath}";

    builderServices.AddDbContextFactory<CBTIdentityDataContext>(options =>
    {
        options.UseSqlite(singleConnectionString);
    }, ServiceLifetime.Transient);
    builderServices.AddDbContextFactory<CBTDataContext>((options) =>
    {
        options.UseSqlite(singleConnectionString);
    }, ServiceLifetime.Transient);

    return builderServices;
}

// 辅助方法:检查目标数据库是否需要更新(可选,根据需求调整)
private static bool NeedUpdateDb(string targetPath)
{
    var assembly = Assembly.GetExecutingAssembly();
    var resourceName = "YourProjectNamespace.Files.psyonicru_localdb.sqlite";
    var resourceInfo = assembly.GetManifestResourceInfo(resourceName);
    var targetFileInfo = new FileInfo(targetPath);
    
    return resourceInfo?.LastWriteTimeUtc > targetFileInfo.LastWriteTimeUtc;
}

3. 验证资源名称正确性

嵌入式资源的名称必须准确,可通过以下代码列出所有嵌入式资源,确认你的数据库文件名称:

var assembly = Assembly.GetExecutingAssembly();
foreach (var res in assembly.GetManifestResourceNames())
{
    System.Diagnostics.Debug.WriteLine($"Resource: {res}");
}

运行Windows端,查看输出日志中的资源名称,替换代码中的resourceName。

4. 验证Android端文件路径

运行Android应用后,使用Android Studio的Device File Explorer导航到/data/user/0/com.companyname.cbt.maui.blazor/files/,确认psyonicru_localdb.sqlite存在且文件大小与原文件一致。

5. 额外排查点

  • 确保SQLite版本与SQLite Studio使用的版本兼容(MAUI默认的SQLitePCLRaw版本通常无问题)。
  • 彻底移除代码中对AppDomain.CurrentDomain.BaseDirectory的依赖,统一使用FileSystem.AppDataDirectory获取路径。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 21:05:07