首页 > 解决方案 > 如何在部署/构建之间以 Xamarin 形式维护 SQLite 数据库状态

问题描述

我有一个 Xamarin Forms 应用程序,它使用 SQLite 来持久化数据,并在顶部有一个存储库层抽象。所有这些工作正常,但我无法在部署/构建之间保存数据库,无论是在模拟器中还是使用物理设备(Android)。

我的 App.xaml.cs 目前像这样初始化数据库:

var sqlite = Container.Resolve<ISQLiteConnectionService>();
var repository = Container.Resolve<IPersonRepository>();

if (!repository.DatabaseExists())
{
    sqlite.CreateDatabase();
}

if (repository.GetLoggedInUserOrReturnNull() != null)
{
    await NavigationService.NavigateAsync("NavigationPage/ActivityFeed");
}
else
{
    await NavigationService.NavigateAsync("NavigationPage/Login");
}

DatabaseExists检查如下:

try
{
    var dbConnection = SQLiteConnectionService.GetAsyncConnection();

    return dbConnection.TableMappings.Any(m => m.MappedType.Name == typeof(PersonDBModel).Name);
}

连接服务类如下所示:

public class SqliteConnectionService : ISQLiteConnectionService
{
    private readonly string _databasePath;
    private SQLiteAsyncConnection _sqLiteAsyncConnection;
    private SQLiteConnection _sqLiteConnection;

    public SqliteConnectionService(IFileHelper fileHelper)
    {
        if (fileHelper == null)
        {
            throw new ArgumentNullException(nameof(fileHelper));
        }

        _databasePath = fileHelper.GetLocalFilePath(Constants.DB_NAME);

        if (!_databasePath.Contains("UWP"))
        {
            if (File.Exists(_databasePath))
            {
                File.Delete(_databasePath);
            }

            File.Create(_databasePath);
        }
    }

    public SQLiteAsyncConnection GetAsyncConnection()
    {
        return _sqLiteAsyncConnection ?? (_sqLiteAsyncConnection = new SQLiteAsyncConnection(_databasePath, SQLiteOpenFlags.Create |
                                                                                                            SQLiteOpenFlags.SharedCache |
                                                                                                            SQLiteOpenFlags.ReadWrite, false));
    }

    public SQLiteConnection GetConnection()
    {
        return _sqLiteConnection ?? (_sqLiteConnection = new SQLiteConnection(_databasePath, SQLiteOpenFlags.Create |
                                                                                             SQLiteOpenFlags.SharedCache |
                                                                                             SQLiteOpenFlags.ReadWrite, false));
    }

    public async Task CreateDatabaseAsync()
    {
        var dbConnection = GetAsyncConnection();
        await dbConnection.CreateTableAsync<PrivacySettingsDBModel>();
        await dbConnection.CreateTableAsync<PersonDBModel>();
        ...
    }

    public void CreateDatabase()
    {
        var dbConnection = GetConnection();
        dbConnection.CreateTable<PrivacySettingsDBModel>();
        dbConnection.CreateTable<PersonDBModel>();
        ...
    }
}

然后,SQLite 文件的路径.db3由为每个平台创建的文件帮助程序确定,特别是为 Android:

public class FileHelper : IFileHelper
{
    public string GetLocalFilePath(string filename)
    {
        if (string.IsNullOrWhiteSpace(filename))
        {
            throw new ArgumentException("Value cannot be null or white space.", nameof(filename));
        }

        var path = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);

        return Path.Combine(path, filename);
    }
}

我看不出在应用程序重新启动或应用程序重新部署之间没有保留此数据库文件的任何原因。

选项:

工具 -> Xamarin -> Android 设置 -> 在部署之间保留设备上的应用程序数据缓存

被检查了,所以我很难过。

有没有人遇到过这个问题,或者代码中是否有明显的问题?

标签: c#sqlitexamarinxamarin.forms

解决方案


原来是用户错误!

虽然我在 UWP 上遇到了数据库问题。

修改后的连接服务代码很简单:

_databasePath = fileHelper.GetLocalFilePath(Constants.DB_NAME);

if (!File.Exists(_databasePath))
{
    File.Create(_databasePath);
}

现在似乎也适用于 UWP。

Xamirin.Forms 更新解决了这个问题,或者我的机器正在运行。

希望这可以帮助任何想要使用 Prism 和 SQLite 的人。


推荐阅读