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

从Xamarin Android迁移SQLite数据库至.NET Maui应用的问题

问题描述

计划将现有Xamarin Android应用升级为.NET Maui版本,需保留用户已有的SQLite数据库。Xamarin应用使用SQLiteOpenHelper,读取到的user_version为8;但在Maui应用中执行相同查询PRAGMA user_version时,返回的user_version为0。两个应用使用相同的连接字符串:Data Source=/data/user/0/<my app id>/databases/my_database.db。

Xamarin 相关代码

public partial class BaseHandler : Android.Database.Sqlite.SQLiteOpenHelper
{
    private const string DB_NAME = "my_database.db";
    Android.Content.Context _context;

    private Android.Database.Sqlite.SQLiteDatabase _db = null;
    public BaseHandler (IContext context) : base (context.AppContext, DB_NAME, null, DB_VERSION)
    {
        _context = context.AppContext;
        _db = WritableDatabase;
        var version = ExecuteScalar(@"PRAGMA user_version");
    }

    public override void OnCreate (Android.Database.Sqlite.SQLiteDatabase db)
    {
        var sqls = this.CreateDatabaseSql();
        this.DoSql(db, sqls);
        var version = ExecuteScalar(@"PRAGMA user_version");
    }
}

Maui 相关代码(使用sqlite-net-pcl包)

public async Task<IEnumerable<MyItem>> GetAllItems()
{
    var sql = "SELECT * FROM MY_ITEMS;";

    try
    {
        await using var cnn = GetCnn();
        return await cnn.QueryAsync<MyItem>(sql);
    }
    catch (Exception ex)
    {
        throw ex;
    }
}
问题排查方向及解决办法
  1. 确认user_version的查询方式是否正确
    你提供的Maui代码仅展示了查询表数据的逻辑,未包含获取user_version的代码。如果用QueryAsync执行PRAGMA user_version,会因为该查询返回单个值而非结果集,导致无法正确解析,最终得到默认值0。正确的做法是使用ExecuteScalarAsync获取单值结果:

    await using var cnn = GetCnn();
    var userVersion = await cnn.ExecuteScalarAsync<long>("PRAGMA user_version");
    
  2. 检查应用包名与签名一致性
    Android应用的沙箱权限由包名和签名共同决定,如果Maui应用的包名或签名与原Xamarin应用不一致,会无法访问原数据库所在的沙箱目录。即使连接字符串路径相同,实际访问的也会是Maui应用沙箱内的新数据库(此时user_version自然为0)。必须确保Maui应用的包名、签名与原Xamarin应用完全一致。

  3. 注意SQLite库的版本与行为差异
    Xamarin的SQLiteOpenHelper依赖Android系统自带的SQLite库,而sqlite-net-pcl通常绑定独立的SQLite版本。两者对数据库版本的处理逻辑有差异:SQLiteOpenHelper会在构造时自动将DB_VERSION赋值给user_version,而sqlite-net-pcl不会自动处理版本同步。如果数据库确实存在,可尝试手动读取并验证版本,必要时通过PRAGMA user_version = 8手动设置(需确保数据库结构匹配)。

  4. 验证数据库连接的权限与模式
    确保sqlite-net-pcl的连接使用读写模式,可在连接字符串中显式指定:

    Data Source=/data/user/0/<my app id>/databases/my_database.db;Mode=ReadWrite
    

    同时检查数据库文件的权限,确保Maui应用拥有读写该文件的权限(包名一致的情况下通常无需额外配置)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 05:22:30