将数据存储在本地 SQLite.NET 数据库中

把上一节文件存储的多便签App,改造为使用 SQLite.NET 本地数据库持久化存储便签。 对比:之前是把每条便签存成独立txt文件;现在全部便签存入单个SQLite数据库文件 Notes.db3

安装 sqlite-net-pcl NuGet包

  1. 右键Notes项目 → 管理 NuGet 包…
  2. 切换到【浏览】标签,搜索包:sqlite-net-pcl 正确包信息:
    • ID:sqlite-net-pcl
    • 创建者:Frank A. Krueger 注意不要装错同名类似包
  3. 选中包,点击【安装】

修改 Models/Note.cs(数据库实体模型)

替换原有代码,增加SQLite特性标记

using SQLite;
using System;

namespace Notes.Models
{
    public class Note
    {
        [PrimaryKey, AutoIncrement]
        public int ID { get; set; }
        public string Text { get; set; }
        public DateTime Date { get; set; }
    }
}
Code language: JavaScript (javascript)

说明:

  • [PrimaryKey]:标记ID为主键
  • [AutoIncrement]:主键自增,新增记录自动分配唯一ID
  • 不再需要 Filename 属性,改用数据库ID标识每一条便签

新建 Data 文件夹与 NoteDatabase.cs 数据库操作类

  1. 右键项目 → 添加新文件夹,命名:Data
  2. 在Data文件夹右键 → 添加类,命名 NoteDatabase.cs
using System.Collections.Generic;
using System.Threading.Tasks;
using SQLite;
using Notes.Models;

namespace Notes.Data
{
    public class NoteDatabase
    {
        readonly SQLiteAsyncConnection _database;

        public NoteDatabase(string dbPath)
        {
            _database = new SQLiteAsyncConnection(dbPath);
            _database.CreateTableAsync<Note>().Wait();
        }

        // 获取所有便签
        public Task<List<Note>> GetNotesAsync()
        {
            return _database.Table<Note>().ToListAsync();
        }

        // 根据ID查询单条便签
        public Task<Note> GetNoteAsync(int id)
        {
            return _database.Table<Note>()
                            .Where(i => i.ID == id)
                            .FirstOrDefaultAsync();
        }

        // 保存/更新便签:ID=0新增;ID>0修改
        public Task<int> SaveNoteAsync(Note note)
        {
            if (note.ID != 0)
            {
                return _database.UpdateAsync(note);
            }
            else
            {
                return _database.InsertAsync(note);
            }
        }

        // 删除便签
        public Task<int> DeleteNoteAsync(Note note)
        {
            return _database.DeleteAsync(note);
        }
    }
}
Code language: JavaScript (javascript)

SQLiteAsyncConnection:异步数据库连接,避免阻塞UI线程 CreateTableAsync:如果表不存在,则自动创建Note数据表

修改 App.xaml.cs(数据库单例)

using System.IO;
using Xamarin.Forms;
using Notes.Data;

namespace Notes
{
    public partial class App : Application
    {
        static NoteDatabase database;

        public static NoteDatabase Database
        {
            get
            {
                if (database == null)
                {
                    string dbPath = Path.Combine(
                        Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
                        "Notes.db3");
                    database = new NoteDatabase(dbPath);
                }
                return database;
            }
        }

        public App()
        {
            InitializeComponent();
            MainPage = new NavigationPage(new NotesPage());
        }

        protected override void OnStart()
        {
        }

        protected override void OnSleep()
        {
        }

        protected override void OnResume()
        {
        }
    }
}
Code language: PHP (php)

核心知识点:数据库单例模式

  • 整个应用只创建一个 NoteDatabase 对象,复用同一个数据库连接
  • 数据库文件 Notes.db3 存放在应用本地数据目录

修改 NotesPage.xaml.cs 的 OnAppearing

只替换 OnAppearing 方法:

protected override async void OnAppearing()
{
    base.OnAppearing();
    listView.ItemsSource = await App.Database.GetNotesAsync();
}
Code language: JavaScript (javascript)

逻辑:页面每次显示时,从数据库读取全部便签,绑定到ListView列表。

修改 NoteEntryPage.xaml.cs 的保存、删除事件方法

替换 OnSaveButtonClickedOnDeleteButtonClicked

async void OnSaveButtonClicked(object sender, EventArgs e)
{
    var note = (Note)BindingContext;
    note.Date = DateTime.UtcNow;
    await App.Database.SaveNoteAsync(note);
    await Navigation.PopAsync();
}

async void OnDeleteButtonClicked(object sender, EventArgs e)
{
    var note = (Note)BindingContext;
    await App.Database.DeleteNoteAsync(note);
    await Navigation.PopAsync();
}
Code language: JavaScript (javascript)
  • 保存时自动设置当前UTC时间
  • SaveNoteAsync内部自动判断是新增还是更新记录
  • 操作完成后返回列表页

页面XAML不用改动

NotesPage.xaml、NoteEntryPage.xaml 界面代码保持不变,因为绑定属性 TextDate 还在Note模型中。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注