在 Windows 应用中使用 SQLite 数据库

可以使用 SQLite 在用户设备上的轻量级数据库中存储和检索数据。 本指南介绍如何在 Windows 应用 SDK 应用中执行此操作。

使用 SQLite 进行本地存储一些好处

✔️ SQLite 具有轻量和独立的特点。 它是没有其他任何依赖项的代码库。 无需进行任何配置。

✔️ 没有数据库服务器。 客户端和服务器在同一进程中运行。

✔️ SQLite 位于公共域中,因此你可以自由地使用它并将它与应用一起分配。

✔️ SQLite 可跨平台和体系结构工作。

可在此处了解有关 SQLite 的详细信息。

选择抽象层

我们建议使用由 Microsoft 构建的 Entity Framework Core 或开源 SQLite 库

Entity Framework Core

Entity Framework (EF) 是一个对象关系映射程序,可用于使用特定于域的对象处理关系数据。 如果已使用此框架处理其他 .NET 应用中的数据,则可以在 Windows 应用 SDK 应用中使用相同的代码,它将处理对连接字符串的相应更改。

若要试用,请参阅 EF Core 入门

SQLite 库

Microsoft.Data.Sqlite 库可在 System.Data.Common 命名空间中实现接口。 Microsoft 将主动保留这些实现,它们提供了围绕低级别本机 SQLite API 的直观的包装器。

本指南的其余部分将帮助你使用此库。

将解决方案设置为使用 Microsoft.Data.SQlite 库

我们将从基本 Windows 应用 SDK 项目开始,然后安装 SQLite NuGet 包。

所有受支持的 Windows 版本都支持 SQLite,因此你的应用无需将 SQLite 库打包。 相反,应用可以使用随 Windows 一起安装的 SQLite 版本。 这将带来几个方面的好处。

✔️ 减小了应用程序的大小,因为你不必下载 SQLite 二进制文件然后将其打包为应用程序的一部分。

✔️ 如果 SQLite 发布了针对 SQLite 中的 bug 和安全漏洞的重要修复程序,你就不必向用户推送你的应用的新版本。 Windows 版本的 SQLite 由 Microsoft 与 SQLite.org 协作维护。

✔️ 应用加载时间可能更短,因为 SDK 版本的 SQLite 很有可能已被加载到内存中。

首先向名为 DataAccess 的项目添加一个类。 如果计划与其他客户端代码共享数据访问逻辑,可使用 .NET 类库项目来包含数据访问代码,但我们不会在本示例中使用该类库。

  1. 右键单击该解决方法,然后单击“管理解决方案的 NuGet 包”

    Visual Studio“解决方案资源管理器”的屏幕截图,其中右键单击了项目,并突出显示了“管理 NuGet 包”选项。

    此时,你已经有一个选择。 你可以使用 Windows 附带的 SQLite 版本,如果你出于某种原因要使用特定版本的 SQLite,则可以在程序中包含 SQLite 库。 我们将使用 Windows 附带的 SQLite 版本。

  2. 选择“浏览”选项卡,搜索“Microsoft.Data.SQLite”包,然后安装最新稳定版

    SQLite NuGet 包

在 SQLite 数据库中添加和检索数据

我们将执行以下操作:

1️⃣ 准备数据访问类。

2️⃣ 初始化 SQLite 数据库。

3️⃣ 将数据插入到 SQLite 数据库。

4️⃣ 从 SQLite 数据库检索数据。

5️⃣ 添加基本用户界面。

准备数据访问类

在项目中打开 DataAccess 类并将其设为静态。

注意

尽管我们的示例将数据访问代码放在静态类中,但这只是一个设计选择,并且是全凭自愿。

public static class DataAccess
{
}

将以下 using 语句添加到此文件顶部。

using Microsoft.Data.Sqlite;
using System.Collections.Generic;

初始化 SQLite 数据库

DataAccess 类添加一个初始化 SQLite 数据库的方法。

public async static void InitializeDatabase()
{ 
    await ApplicationData.Current.LocalFolder
            .CreateFileAsync("sqliteSample.db", CreationCollisionOption.OpenIfExists);
    string dbpath = Path.Combine(ApplicationData.Current.LocalFolder.Path,
                                 "sqliteSample.db");
    using (var db = new SqliteConnection($"Filename={dbpath}"))
    {
        db.Open();

        string tableCommand = "CREATE TABLE IF NOT " +
            "EXISTS MyTable (Primary_Key INTEGER PRIMARY KEY, " +
            "Text_Entry NVARCHAR(2048) NULL)";

        var createTable = new SqliteCommand(tableCommand, db);

        createTable.ExecuteReader();
    }
}

注意

上面使用 ApplicationData 成员的代码仅适用于在应用容器中运行的打包应用。 所有其他 Windows 应用应通过 ApplicationDataManager 类访问 ApplicationData 成员。

此代码将创建 SQLite 数据库并将其存储在应用程序的本地数据存储区中。

在此示例中,我们将数据库命名为 sqlliteSample.db,但你可以使用任何想要的名称,只要你在你实例化的所有 SqliteConnection 对象中使用该名称。 在生产应用程序中,连接信息(如数据库文件名)应存储在应用配置中,而不是进行硬编码(请参阅使用 Visual Studio Connected Services 添加 Azure 应用配置)。

在项目的 App.xaml.cs 文件的构造函数中,调用 DataAccess 类的 InitializeDatabase 方法。 这将确保每次应用启动时都创建或打开数据库。

public App()
{
    this.InitializeComponent();

    DataAccess.InitializeDatabase();
}

将数据插入到 SQLite 数据库

DataAccess 类添加一个将数据插入到 SQLite 数据库的方法。 此代码在查询中使用参数以阻止 SQL 注入攻击。

public static void AddData(string inputText)
{
    string dbpath = Path.Combine(ApplicationData.Current.LocalFolder.Path,
                                 "sqliteSample.db");
    using (var db = new SqliteConnection($"Filename={dbpath}"))
    {
        db.Open();

        var insertCommand = new SqliteCommand();
        insertCommand.Connection = db;

        // Use parameterized query to prevent SQL injection attacks
        insertCommand.CommandText = "INSERT INTO MyTable VALUES (NULL, @Entry);";
        insertCommand.Parameters.AddWithValue("@Entry", inputText);

        insertCommand.ExecuteReader();
    }

}

从 SQLite 数据库检索数据

添加从 SQLite 数据库的表中获取所有数据行的方法。

public static List<string> GetData()
{
    var entries = new List<string>();
    string dbpath = Path.Combine(ApplicationData.Current.LocalFolder.Path,
                                 "sqliteSample.db");
    using (var db = new SqliteConnection($"Filename={dbpath}"))
    {
        db.Open();
        var selectCommand = new SqliteCommand
            ("SELECT Text_Entry from MyTable", db);

        SqliteDataReader query = selectCommand.ExecuteReader();

        while (query.Read())
        {
            entries.Add(query.GetString(0));
        }
    }

    return entries;
}

Read 方法将向前浏览返回的数据的行。 如果有剩下的行,它将返回 true,否则返回 false

GetString 方法返回字符串形式的指定列的值。 它将接受一个整数值,该值表示所需的数据的从零开始的列序号。 你可以使用类似的方法,例如 GetDataTimeGetBoolean。 请根据列包含的数据的类型选择方法。

在此例子中,序号参数并不重要,因为我们选择了单个列中的所有条目。 但是,如果多个列是你的查询的一部分,请使用序号值获取你要从中拉取数据的列。

添加基本用户界面

在项目的 MainWindow.xaml 文件中,添加以下 XAML。

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <StackPanel>
        <TextBox x:Name="Input_Box"/>
        <Button Click="AddData">Add</Button>
        <ListView x:Name="Output">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding}"/>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </StackPanel>
</Grid>

此基本用户界面为用户提供了 TextBox,可用于键入我们将添加到 SQLite 数据库的字符串。 我们要将此 UI 中的 Button 连接到事件处理程序,后者将从 SQLite 数据库检索数据然后在 ListView 中显示数据。

MainWindow.xaml.cs 文件中,添加以下处理程序。 这是我们关联到 UI 中的 ButtonClick 事件的方法。

private void AddData(object sender, RoutedEventArgs e)
{
    DataAccess.AddData(Input_Box.Text);

    Output.ItemsSource = DataAccess.GetData();
}

我们还需要确保在应用程序启动时加载所有现有数据。 向 MainWindow 构造函数添加一行代码以调用 GetData()

public MainWindow()
{
    this.InitializeComponent();

    Output.ItemsSource = DataAccess.GetData();
}

完成了。 探索 Microsoft.Data.Sqlite 以了解 SQLite 数据库的其他功能。 查看下面的链接,了解在 Windows 应用中使用数据的其他方法。

将你的应用直接连接到 SQL Server 数据库

请参阅在 Windows 应用中使用 SQL Server 数据库

在跨不同平台的不同应用之间共享代码

参阅在桌面应用和 UWP 应用之间共享代码

使用 Azure SQL 后端添加大纲/细节页面

参阅客户订单数据库示例