Xamarin.forms备份SQLite数据库 [英] Xamarin.forms Backup a SQLite database

查看:98
本文介绍了Xamarin.forms备份SQLite数据库的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的Xamarin.forms应用程序(Android)集成了一个SQLite数据库,这要归功于我在这里找到的示例:

My Xamarin.forms application (Android) integrates a SQLite database, which I can manage correctly thanks to the example I found here: https://docs.microsoft.com/fr-fr/xamarin/get-started/quickstarts/database

我的第一个问题是:如何保存这个notes.db3文件(在Onedrive或可能的Google驱动器上).

My first question is: how to save this notes.db3 file (on Onedrive or possibly Google drive).

我的第二个问题:如何为应用程序提供一个包含带有数据表的数据库.根据我在互联网上发现的信息,我了解到您需要将预填充的文件sqlite.db3复制到Resources文件夹,然后将此文件和代码复制到应用程序文件夹.

My second question: how to provide the application with a database containing tables with data. I understand, from what I found on the internet, that you need to copy the pre-filled file sqlite.db3 to the Resources folder, and then copy this file with code to the application folder.

我进行了很多搜索,但是我找不到能够执行此操作的确切代码.谢谢您的帮助,这将非常有用,因为有关此主题的文档很少.

I searched a lot, but I couldn't find the exact code to be able to do it. Thank you for helping me, it would be very useful because there is very little documentation on this subject.

这是第二个问题的答案:

Edit : Here is the answer to the second question:

  1. 当新用户首次运行该程序时,我使用该程序用有用的数据填充表格.
  2. 我以编程方式将SQLite文件复制到可通过外部应用程序访问的文件夹中:Android Studio(Visual Studio 2019中Android Device Monitor实用工具的文件管理器不起作用!).这是代码:

使用Xamarin.Essentials的
using Xamarin.Essentials;
using FileSystem = Xamarin.Essentials.FileSystem;

public void CopyDBToSdcard(string dbName)
        {
            var dbPath = Path.Combine(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), dbName));
            string destPath = Path.Combine("/sdcard/Android/data/com.aprisoft.memocourses/files", dbName);
            //
            if (File.Exists(dbPath))
            {
                if (File.Exists(destPath))
                {
                    File.Delete(destPath);
                }
                File.Copy(dbPath, destPath);
            }
        }

  1. 我将此预填充的SQLite文件复制到主项目根目录的应用程序中.在该文件的属性中,我将嵌入式资源"指示为嵌入资源".在构建操作"中.

  1. I copy this pre-filled SQLite file into my application, at the root of the main project. In the properties of this file, I indicate "Embedded resource" in "Build action".

首次运行该程序时,它将检查是否找到SQLite文件.如果找不到,请使用Dirk在此处给出的代码进行复制将该文件放到特殊文件夹"LocalApplicationData"中.这是代码:

When the program is run for the first time, it checks whether it finds the SQLite file. If it cannot be found, I use the code given by Dirk here to copy the file into the special folder "LocalApplicationData" Here is the code:

public void CopyDB_FR(string filename)
        {
            var embeddedResourceDb = Assembly.GetExecutingAssembly().GetManifestResourceNames().First(s => s.Contains(filename));
            var embeddedResourceDbStream = Assembly.GetExecutingAssembly().GetManifestResourceStream(embeddedResourceDb);

            var dbPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), filename);
            //
            if (!File.Exists(dbPath))
            {
                using (var br = new BinaryReader(embeddedResourceDbStream))
                {
                    using (var bw = new BinaryWriter(new FileStream(dbPath, FileMode.Create)))
                    {
                        var buffer = new byte[2048];
                        int len;
                        while ((len = br.Read(buffer, 0, buffer.Length)) > 0)
                        {
                            bw.Write(buffer, 0, len);
                        }
                    }
                }
            }

        }

我将线程保持打开状态,因为我还没有第一个问题的答案.任何帮助将不胜感激.谢谢.

I leave the thread open, because I don't have an answer to my first question yet. Any help will be appreciated. Thank you.

我遵循了Microsoft的示例建立连接使用Graph API将Azure连接到我的应用程序,它的工作原理是:连接正常,我可以检索用户数据.但是,我找不到将文件复制到Onedrive的方法.我正在使用以下代码:

Edit 2: I followed Microsoft's exemple to build a connection to Azure into my app using Graph APIs, and it works: the connection is fine, and I can retrieve user data. However, I can't find a way to copy a file to Onedrive. I am using the following code:

await (Application.Current as App).SignIn();
            btnConnect.IsEnabled = false;
            //
            // put user's files
            
            string path = Path.Combine("/data/data/com.ApriSoft.memocourses/files/Backup", "MemoCourses.db3");
            byte[] data = System.IO.File.ReadAllBytes(path);
            Stream stream = new MemoryStream(data);
            
            await App.GraphClient.Me
                    .Drive
                    .Root
                    .ItemWithPath("/Backup/MemoCourses.db3")
                    .Content
                    .Request()
                    .PutAsync<DriveItem>(stream);

            ;

但是几分钟后,出现以下错误:

But after a few minutes I got the following error:

身份验证错误代码:GeneralException消息:发送请求时发生错误.

Authentication Error Code: GeneralException Message: An error occured sending the request.

我的代码不正确吗?请帮助我,我想完成我的应用程序.非常感谢.

Is my code incorrect? Please help me, I would like to finish my app. Thank you very much.

推荐答案

我终于设法备份并将SQLite数据库还原到OneDrive.它既简单又复杂.如果遵循此处随Graph和Azure提供的Microsoft示例,这很简单: https://docs.microsoft.com/zh-us/graph/tutorials/xamarin?tutorial-step = 1 而且很复杂,因为此示例未说明如何将文件复制到OneDrive.这是我所做的:我按照Microsoft的分步示例将其应用于我的应用程序.

I finally managed to back up and restore my SQLite database to OneDrive. It’s both simple and complicated. It's simple if you follow the example Microsoft provided with Graph and Azure here: https://docs.microsoft.com/en-us/graph/tutorials/xamarin?tutorial-step=1 And it's complicated because this example doesn't explain how to copy files to OneDrive. Here is what I did: I followed Microsoft's step-by-step example by applying it to my application.

在Azure管理中心中,我添加了配置的权限:

In the Azure admin center, I added in the configured permissions:

Device.Read
Files.ReadWrite.All
Files.ReadWrite.AppFolder

后者是最重要的.

在我的应用程序中:在OAuthSettings.cs中,通过向Scopes常量的定义中添加Files.ReadWrite.AppFolder来修改以下行:

In my application: In OAuthSettings.cs, the following line is modified by adding Files.ReadWrite.AppFolder to the definition of the Scopes constant:

Public const string Scopes = "User.Read Calendars.Read Files.ReadWrite.AppFolder";

这对于访问OneDrive上的应用程序文件夹非常重要.在与SQLite数据库备份相对应的方法中,下面是要放入的代码:

This is very important to have access to the application folder on OneDrive. In the method that corresponds to the backup of the SQLite database, here is the code to put:

Stream contentStream = null;
//
var path = await App.GraphClient
                        .Me
                        .Drive
                        .Special
                        .AppRoot
                        .ItemWithPath("MemoCourses.db3")
                        .Request()
                        .GetAsync();


//
try
{
    //foundFile = await path.Request().GetAsync();
    if (path == null)
    {
        await DisplayAlert("Attention", "Backup file not found", "OK");
    }
    else
    {
        contentStream = await App.GraphClient.Me
                                    .Drive
                                    .Special
                                    .AppRoot
                                    .ItemWithPath("MemoCourses.db3")
                                    .Content
                                    .Request()
                                    .GetAsync();

         
        var destPath = Path.Combine(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), dbName));
        var driveItemFile = System.IO.File.Create(destPath);
        contentStream.Seek(0, SeekOrigin.Begin);
        contentStream.CopyTo(driveItemFile);
        //
    }
}
catch (Exception ex)
{
    var error = ex;
    await DisplayAlert("Attention", error.ToString(), "OK");
}

dbName包含SQLite文件的名称.

dbName contains the name of the SQLite file.

对于数据库的恢复:

var dbPath = Path.Combine(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), dbName));
byte[] data = System.IO.File.ReadAllBytes(dbPath);
Stream stream = new MemoryStream(data);
//
try
{
    await App.GraphClient.Me
        .Drive
        .Special
        .AppRoot
        .ItemWithPath("MemoCourses.db3")
        .Content
        .Request()
        .PutAsync<DriveItem>(stream);
}
catch
{
    await DisplayAlert("Attention", "Problem during file copy...", "OK");
}

在我的应用程序中,一切正常.我希望我已经帮助那些仍在寻找解决此问题的人.如果您需要更多信息,请随时问我任何问题.

In my app everything is working perfectly. I hope I have helped those who are still looking for a solution to this problem. Please don't hesitate to ask me any questions if you want more information.

这篇关于Xamarin.forms备份SQLite数据库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆