UWP: 在 UWP 中使用 Entity Framework Core 操作 SQLite 数据库
在应用中使用 SQLite 数据库来存储数据是相当常见的。在 UWP 平台中要使用 SQLite,一般会使用 SQLite for Universal Windows Platform 和 SQLite PCL 之类的库,前者是 SQLite 引擎库,而后者则提供了用于操作数据库的 API ,不过自从 Windows Fall Creators Update 之后,我们有了新的选择。
由于 UWP 在其 Windows Fall Creators Update SDK 中增加对 .NET Standard 2.0 的支持,并且 Entity Framework Core 2.0(以下简称 EF Core)也支持 .NET Standard 2.0,这就使得我们能在 UWP 应用中使用 EF Core 来操作 SQLite 数据库。相比前者,使用 EF Core 最明显的优点是可以使用 Entity Framework 的特性(如 Fluent API、Migration 等);此外,由于 EF Core 实现了 .NET Standard 并且还在继续迭代过程中,这些方面都能够成为我们使用 EF Core 的原因。
接下来,我们将会通过一个简单的例子来看如何在 UWP 中使用 EF Core,在开始之前,你的环境必须满足以下几个条件:
- Windows 10 Fall Creators Update (10.0.16299.0);
- 安装了 .NET Core 2.0 SDK(或更高版本);
- Visual Studio 2017 的版本为 15.4 或更高;
实现
1. 项目创建
创建一个 UWP 项目,名为 LSNote,这是一个可以管理笔记的应用。注意:其最小版本,应该为 Windows Fall Creators Update,如下:

然后,在解决方案中添加一个 .NET Standard 项目,名为 LSNote.Model,我们要在这个项目中添加一些 Model。接着,为 UWP 项目添加对这个 .NET Standard 项目的引用。最终的项目结构如下:

需要说明的是:如果不使用 EF Core 的 Migration 功能,则不需要再创建后面的 .NET Standard 项目(后面我们会提到 Migration);另外,将 Model 单独放在一个项目中,也可以使它与其它实现 .NET Standard 的项目共享,如 ASP.net Core 或 WPF/WinForm(目标框架应为 .NET Framework 4.6.1 或更高)。
2. Model 项目编码与配置
首先,为它添加对 EF Core 的引用,通过 NuGet,添加对以下两个包的引用:
Install-Package Microsoft.EntityFrameworkCore.Sqlite
Install-Package Microsoft.EntityFrameworkCore.Tools
其中,第一个是 EF Core 库本身,而二个提供了用于 Migration 的工具。
这里简单解释一下 Migration(译,迁移),它以增量的方式来修改数据库以及表结构,使 EF Core 的模型与数据库保持一致,并且不会影响数据库中现有的数据。
接下来,在 LSNote.Model 项目中,添加以下代码,其中包括三个类:
using Microsoft.EntityFrameworkCore; namespace LSNote.Model
{
public class Note
{
public int Id { get; set; }
public string Title { get; set; }
public string Content { get; set; }
public Category Category { get; set; }
} public class Category
{
public int Id { get; set; }
public string Name { get; set; }
} public class NoteDbContext : DbContext
{
public DbSet<Category> Categories { get; set; } /// <summary>
/// 数据库文件的路径
/// </summary>
public string DbFilePath { get; set; } public DbSet<Note> Notes { get; set; } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
base.OnConfiguring(optionsBuilder); // 设置数据库文件的路径
optionsBuilder.UseSqlite($"Data Source={DbFilePath}");
} protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder); // 必填
modelBuilder.Entity<Category>().Property(m => m.Name).IsRequired();
modelBuilder.Entity<Note>().Property(m => m.Title).IsRequired();
}
}
}
其中:
- Note:表示一个笔记项;
- Category: 表示一个类别,即笔记的类别;
- NoteDbContext: 这个类继承自 DbContext,它里面包括了若干了 DbSet<T> 的属性,代表对应的数据表;
此外在 NoteDbContext 中,我们重载的两个方法意义分别如下:
- OnConfiguring: 配置数据库,每当 DbContext 实例被创建时,它都会被执行;
- OnModelCreating: 配置 Model 及其属性,并最终影响数据表以及字段;
然后,为了使用 Migration,我们还要编辑 LSNote.Model 项目的属性(编辑 LSNote.Model.csproj):
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup>
<TargetFrameworks>netcoreapp2.0;netstandard2.0</TargetFrameworks>
<GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="microsoft.entityframeworkcore.sqlite" Version="2.0.1" />
<PackageReference Include="microsoft.entityframeworkcore.tools" Version="2.0.1" />
</ItemGroup>
</Project>
注意其中增加的加粗部分,我们使当前项目的目标框架为 .netcoreapp2.0 和 .netstandard2.0,另外增加了 GenerateRuntimeConfigurationFiles 节点。
此时,设置 LSNote.Model 为启动项目,然后在 PMC(Package Manager Console)中,确保 Defalut project 也是 LSNote.Model,之后,输入以下命令:
Add-Migration Init
其中 Init 是本次 Migration 的名称。之后,可以看到在项目中生成了一个 Migrations 文件夹,其下包括了代表每次 Migration 的类文件,它们继承自 Migration 类,如下:

注意:执行 Migration 命令,必须使 LSNote.Model 项目为启动项,这是因为目前版本的 EF Core Tools 还不支持 UWP 这种类型的启动项目。
3. 在 UWP 项目中调用
首先,为 UWP 项目也添加对 EF Core 的引用,执行命令:
Install-Package Microsoft.EntityFrameworkCore.Sqlite
接下来,在 App.xaml.cs 文件中,增加以下代码(加粗部分):
using Microsoft.EntityFrameworkCore;
public App()
{
this.InitializeComponent();
this.Suspending += OnSuspending;
DbPath = Path.Combine(ApplicationData.Current.LocalFolder.Path, "notes.db");
try
{
using (var con = new LSNote.Model.NoteDbContext())
{
con.DbFilePath = DbPath;
con.Database.Migrate();
}
}
catch (NotSupportedException ex)
{
}
catch (Exception ex)
{
}
}
public static string DbPath { get; set; }
通过 DatabaseFacade 类的 Migrate 方法,将挂起的 Migration 应用到数据库,如果数据库还没创建,它会先创建数据库;其中 DatabaseFacade 类由 con.Database 属性得到。
然后,我们在 MainPage.xaml.cs 中,添加以下代码:
public sealed partial class MainPage : Page, INotifyPropertyChanged
{
private List<Note> _allNotes; public MainPage()
{
this.InitializeComponent(); this.Loaded += MainPage_Loaded;
} public event PropertyChangedEventHandler PropertyChanged; public List<Note> AllNotes
{
get { return _allNotes; }
set
{
_allNotes = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(AllNotes)));
}
} private void MainPage_Loaded(object sender, Windows.UI.Xaml.RoutedEventArgs e)
{
using (var con = new NoteDbContext())
{
// 设置数据库路径
con.DbFilePath = App.DbPath; // 添加分类
if (con.Categories.ToList().Count == )
{
var cate1 = new Category { Name = "分类A" };
var cate2 = new Category { Name = "分类B" };
con.Categories.AddRange(cate1, cate2);
con.SaveChanges();
} // 添加笔记
con.Notes.Add(new Note { Title = "这是一条记录", Content = "一些备注", Category = con.Categories.First() });
con.SaveChanges(); // 查询
AllNotes = con.Notes.ToList();
}
}
}
在 MainPage.xaml 中添加以下代码:
<Page
...
xmlns:model="using:LSNote.Model"
... <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<ListView x:Name="list" ItemsSource="{x:Bind AllNotes, Mode=OneWay}">
<ListView.ItemTemplate>
<DataTemplate x:DataType="model:Note">
<StackPanel Margin="0,4">
<TextBlock
FontSize="16"
FontWeight="SemiBold"
Text="{x:Bind Title}" />
<TextBlock Text="{x:Bind Content}" />
<TextBlock>
<Run Text="Category:" />
<Run Text="{x:Bind Category.Name}" />
</TextBlock>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
</Page>
这时,将 UWP 项目设置为启动项目,按 F5 运行,即可看到结果:

4. 进一步使用 Migration
前面说过,使用 EF Core,我们可以使用它自身的特性,例如,当我们要对现有的数据库或表结构修改时,使用 Migration 将会非常简单。对于上面的 Note 实体,我们要为它新添加一个 IsDelete 属性,然后再通过 Add-Migration 命令和 Migrate 方法最终影响到数据库。
首先,添加属性:
public bool IsDelete { get; set; }
接下来,仍然要设置 LSNote.Model 为启动项目,并且在 PMC 中确认 Defalut project 也是它,输入命令:
Add-Migration AddIsDeleteField
这时,在 Migrations 文件夹会新生成对应的类文件。
切换启动项目为 UWP 项目,并且在 MainPage.xaml 中增加以下代码(加粗部分):
<DataTemplate x:DataType="model:Note">
<StackPanel Margin="0,4">
<TextBlock
FontSize="16"
FontWeight="SemiBold"
Text="{x:Bind Title}" />
<TextBlock Text="{x:Bind Content}" />
<TextBlock>
<Run Text="Category:" />
<Run Text="{x:Bind Category.Name}" />
</TextBlock>
<TextBlock>
<Run Text="IsDelete:" />
<Run Text="{x:Bind IsDelete}" />
</TextBlock>
</StackPanel>
</DataTemplate>
按 F5 运行,即可看到更新后的结果:
补充的话:关于 Migration
- 对于 SQLite,EF Core 的 Migration 目前还有一些限制,并不能满足所有的功能,如在创建数据表后,再添加外键、添加主键,等。这里有一份完整的限制操作列表;如果在 Migration 中,包括这些操作,将会引发 NotSupportedException。不过,值得注意的是,随着 EF Core 的不断完善,在将来,这些限制都应该会一一实现;
- 另外,建议每次在 Migration 前要备份数据;
总结
本文主要讨论了在 UWP 中如何使用 EF Core,由于两者都依赖并且支持 .NET Standard 2.0,所以在 EF Core 能够被用于 UWP 中,并且运行在任何支持 Win 10 的设备上。接下来,如果你正在开发或者准备开发的应用会用到 SQLite 数据库,不妨试试 EF Core 。
参考资料:
Getting Started with EF Core on Universal Windows Platform
The Secret to Running EF Core 2.0 Migrations from a NET Core or NET Standard Class Library
UWP: 在 UWP 中使用 Entity Framework Core 操作 SQLite 数据库的更多相关文章
- [UWP小白日记-11]在UWP中使用Entity Framework Core(Entity Framework 7)操作SQLite数据库(一)
前言 本文中,您将创建一个通用应用程序(UWP),使用Entity Framework Core(Entity Framework 7)框架在SQLite数据库上执行基本的数据访问. 准备: Enti ...
- UWP开发之ORM实践:如何使用Entity Framework Core做SQLite数据持久层?
选择SQLite的理由 在做UWP开发的时候我们首选的本地数据库一般都是Sqlite,我以前也不知道为啥?后来仔细研究了一下也是有原因的: 1,微软做的UWP应用大部分也是用Sqlite.或者说是微软 ...
- 在服务器中使用 Entity Framework 的 Migration 更新数据库
在开发环境中,每次我们对要对数据库进行更改,比如增加修改表字段等.改好Entity类后,我们只需在Nuget程序包管理控制台运行 update-database 脚本却可: update-databa ...
- 让EF飞一会儿:如何用Entity Framework 6 连接Sqlite数据库
获取Sqlite 1.可以用NuGet程序包来获取,它也会自动下载EF6 2.在Sqlite官网上下载对应的版本:http://system.data.sqlite.org/index.html/do ...
- 如何用Entity Framework 6 连接Sqlite数据库[转]
获取Sqlite 1.可以用NuGet程序包来获取,它也会自动下载EF6 2.在Sqlite官网上下载对应的版本:http://system.data.sqlite.org/index.html/do ...
- Asp.net Core中使用Entity Framework Core CodeFirst
1.安装对应的包 "Microsoft.EntityFrameworkCore.Design": "1.1.0", "Microsoft.Entity ...
- Entity Framework Core 2.0 数据库迁移
看见过几篇其他大神写的关于EFCore2.0的文章.本人有点小白,一开始看文档的时候除了一些基本操作外其他部分几乎没有读懂,我估计会有一部分人跟我一样,因为人家读懂了的早就懂了. 在这里我写一下我自己 ...
- entity framework core 生成 postgresql 数据库实体
.net core 2.0 使用db first 方式生成 表 和context PM 控制台运行命令出错 Scaffold-DbContext "Host=localhost;Databa ...
- Entity Framework Core生成的存储过程在MySQL中需要进行处理及PMC中的常用命令
在使用Entity Framework Core生成MySQL数据库脚本,对于生成的存储过程,在执行的过程中出现错误,需要在存储过程前面添加 delimiter // 附:可以使用Visual Stu ...
随机推荐
- B. Duff in Love
B. Duff in Love time limit per test 2 seconds memory limit per test 256 megabytes input standard inp ...
- #if defined、#if !defined用法
大型程序或者修改别人的程序时,当我们需要定义常量(源文件还是头文件 ),我们就必须返回检查原来此常量是否已经定义, if defined宏 就是用于检测的. 举个例子,如下: #define .... ...
- UEP-弹窗给选中数据赋值
弹窗给选中数据赋值:t/** * 设置分派员 */ function onDispatchMan(){ var rec=ajaxgrid.getCheckedRecords(); if(rec.len ...
- linux日志查看命令
tail tail 命令用于显示文本文件的末尾几行, 对于监控文件日志特别有用 tail example.txt #显示文件 example.txt 的后十行内容: tail -n 20 exampl ...
- 认识Linux分区
前言 今年目标是熟练Linux系统与内核,没有老司机带只能自己慢慢参照鸟哥教程学习了.如果有老司机麻烦指导一下便捷路线,作为这方便的新手还是很乐意接受各位的意见.今天第一步就是熟悉安装Linux中分区 ...
- 【绘图技巧】ps快捷键的用法
Ctrl+N:新建画布 Ctrl+O:打开对话框 F: 在三种画布中切换 Z:缩放工具(临时) Ctrl+0:满画面显示 空格:切换到手(临时) Ctrl+":网 ...
- UML图学习之二 类图
类图(ClassDiagrams)是根据系统中的类以及各类之间的关系描述系统的静态视图.类图不仅显示系统内信息的结构,还描述系统内这些信息的行为.类图的一个重要目的是为其他图(如顺序图.交互图)定义一 ...
- sqllite小型数据库的使用
1.适用场景:免安装型数据库:数据量不大,本地化管理:不依赖其他第三方类库:2.具体使用方法:添加sqllite类库引用 数据库连接定义,数据库以文件形式存储在sqllitedb/solution.d ...
- python_面向对象
什么是面向对象? -- 一种主流编程范式,编程思维框架,世界主流两个方向,面向对象和面向过程. -- 面向是把关注点集中一个具体东西,比如看向手机,也叫面向手机,手机就是一个对象,我们 把手机的属性 ...
- python_py2和py3读写文本区别
python2和python3的区别? python 2 str 对应 python3 bytes python 2 uincode 对应 ...
