把上一节文件存储的多便签App,改造为使用 SQLite.NET 本地数据库持久化存储便签。 对比:之前是把每条便签存成独立txt文件;现在全部便签存入单个SQLite数据库文件 Notes.db3。
安装 sqlite-net-pcl NuGet包
- 右键Notes项目 → 管理 NuGet 包…
- 切换到【浏览】标签,搜索包:
sqlite-net-pcl正确包信息:- ID:sqlite-net-pcl
- 创建者:Frank A. Krueger 注意不要装错同名类似包
- 选中包,点击【安装】


修改 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 数据库操作类
- 右键项目 → 添加新文件夹,命名:
Data - 在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 的保存、删除事件方法
替换 OnSaveButtonClicked 和 OnDeleteButtonClicked:
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 界面代码保持不变,因为绑定属性
Text和Date还在Note模型中。
Previous: 多页 Xamarin.Forms 应用程序 – 多便签管理
Next: Xamarin.Forms 应用程序设置样式