如何在Xamarin.form中使用本地数据库?

时间:2017-03-24 10:44:06

标签: c# sqlite xamarin xamarin.forms

我按照教程一步一步地使用SQLite.net-PCL创建本地数据库。但是,在运行应用程序时,我尝试将数据插入到数据库中,但它却给我一个' System.NullReferenceException'。

我做了什么:

  • 我只使用SQLite.Net-TCL(1.2.1)软件包,并将其添加到Android和iOS中。
  • 我注意到一些教程说我应该在android和iOS上实现sqlite数据库,但是我没有发现教程是用这种方式,或者IFileHelper接口有相同的功能吗?
  • 我将FileHelper接口保存在我的Android文件夹中
  • 调试后,数据库代码通过。因此,插入数据时应该会出现问题。
  • 此行发生异常:if(person.ID!= 0),此行:await App.DB.SaveItemAsync(person);

教程:https://developer.xamarin.com/guides/xamarin-forms/application-fundamentals/databases/

这是我的数据库代码:

using System.Threading.Tasks;
using System.Collections.Generic;
using System;
using SQLite;

namespace DatabaseDemo
{
public class Database
{
    readonly SQLiteAsyncConnection _database;

    public Database(string path)
    {
        _database = new SQLiteAsyncConnection(path);
        _database.CreateTableAsync<Model>().Wait();
    }

    public Task<List<Model>> GetItemsAsync()
    {
        return _database.Table<Model>().ToListAsync();
    }

    public Task<int> SaveItemAsync(Model person)
    {
        if (person.ID != 0)
        {
            return _database.UpdateAsync(person);

        }
        else
        {
            return _database.InsertAsync(person);
        }
    }
}
}

这是我的界面:

<StackLayout Margin="20" VerticalOptions="StartAndExpand">
    <Label Text = "Name"/>
    <Entry Text = "{Binding Name}" />
    <Button Text = "Save" Clicked="OnSaveClicked" />
</StackLayout>

using Xamarin.Forms;
using System;

namespace DatabaseDemo
{
    public partial class DatabaseDemoPage : ContentPage
    {
        public DatabaseDemoPage()
        {
            InitializeComponent();
        }

    async void OnSaveClicked(object sender, EventArgs e)
    {
        var person = (Model)BindingContext;
        await App.DB.SaveItemAsync(person);
    }
}
}

App.cs

using Xamarin.Forms;

namespace DatabaseDemo
{
    public partial class App : Application
    {
        static Database database;
        public static Database DB
        {
            get
            {
                if (database == null)
                {
                    database = new Database(DependencyService.Get<IFileHelper>().GetLocalFilePath("db.db3"));
                }
                return database;
            }
        }

        public App()
        {
            InitializeComponent();

            MainPage = new DatabaseDemoPage();
        }
    }
}

我还创建了一个公共界面,也为Andriod和iOS创建。

using System;
namespace DatabaseDemo
{
    public interface IFileHelper
    {
        string GetLocalFilePath(string filename);
    }
}

2 个答案:

答案 0 :(得分:1)

你必须创建Android端......

[assembly: Dependency(typeof(FileHelper))]
namespace Todo.Droid
{
    public class FileHelper : IFileHelper
    {
        public string GetLocalFilePath(string filename)
        {
            string path = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
            return Path.Combine(path, filename);
        }
    }
}

Here all info

定义接口后,使用DependencyService获取实现并获取本地文件路径(请注意,此接口尚未实现)。以下代码获取App.Database属性中的实现:

static TodoItemDatabase database;

public static TodoItemDatabase Database
{
  get
  {
    if (database == null)
    {
      database = new TodoItemDatabase(DependencyService.Get<IFileHelper>().GetLocalFilePath("TodoSQLite.db3"));
    }
    return database;
  }
}

TodoItemDatabase构造函数如下所示:

public TodoItemDatabase(string dbPath)
{
  database = new SQLiteAsyncConnection(dbPath);
  database.CreateTableAsync<TodoItem>().Wait();
}

此方法创建一个在应用程序运行时保持打开的单个数据库连接,因此避免了每次执行数据库操作时打开和关闭数据库文件的费用。

答案 1 :(得分:1)

通过以下代码解决:

    public DatabaseDemoPage()
    {
        InitializeComponent();
        this.BindingContext = new Model();
    }