EF Core 和 Xamarin 入门

在本教程中,你将创建一个 Xamarin.Forms 应用,该应用使用 Entity Framework Core 对 SQLite 数据库执行数据访问。

可使用 Windows 版 Visual Studio 或 Visual Studio for Mac 来执行本教程中的操作。

提示

可在 GitHub 示例中查看此文章的示例。

先决条件

安装以下工具之一:

文档提供每个平台的详细分步安装说明

下载并运行示例项目

若要运行和浏览此示例应用程序,请下载 GitHub 上的代码。

下载后,在 Visual Studio 或 Visual Studio for Mac 中打开解决方案文件 EFGettingStarted.sln,并在所选平台上运行应用程序。

应用首次启动时,将填充本地 SQLite 数据库(其中包含两个表示博客的条目)。

Screenshot of all blogs list page

单击工具栏中的“添加”按钮

随即将显示一个新的页面,你可在该页面输入新博客的相关信息。

Screenshot of new blog edit page

填写所有信息,然后单击工具栏中的“保存”。 新博客将保存到应用的 SQLite 数据库中,并显示在列表中。

你可单击列表中的一个博客条目,并查看该博客的任何帖子。

Screenshot of blog posts list page

在工具栏中,单击“添加”

此时将显示一个页面,你可在该页面中填写新博客文章的相关信息。

Screenshot of add new post page

填写所有信息,然后单击工具栏中的“保存”

新文章将与上一步中单击的博客文章关联,它将保存到应用的 SQLite 数据库并在列表中显示。

返回到博客列表页。 然后单击工具栏中的“全部删除”。 所有博客及其对应的文章随后都将从应用的 SQLite 数据库中删除。

Screenshot of app with all blogs deleted

浏览代码

以下各部分将展示示例项目中的代码,该项目会搭配 EF Core 使用 Xamarin.Forms 从 SQLite 数据库读取、创建、更新和删除数据。

本文假设你熟悉 Xamarin. Forms 的显示数据在页面之间导航主题。

重要

Entity Framework Core 使用反射来调用 Xamarin.iOS 链接器在发布模式配置中可能会去除的函数。 可以通过以下两种方法之一来避免这种情况。

  • 第一种方法是将 --linkskip System.Core 添加到“iOS 生成”选项中的“其他 mtouch 参数”。
  • 或者,将 Xamarin.iOS“链接器行为”设置为“iOS 生成”选项中的 Don't Link本文详细介绍了 Xamarin.iOS 链接器,包括如何在 Xamarin.iOS 上设置行为。 (此方法并不理想,因为它可能会导致拒绝存储)。

Entity Framework Core NuGet 包

若要使用 EF Core 创建 Xamarin. Forms 应用,请将要以其为目标的 EF Core 数据库提供程序的包安装到 Xamarin.Forms 解决方案中的所有项目。 本教程使用 SQLite 提供程序。

Xamarin.Forms 解决方案的每个项目中都需要以下 NuGet 包。

  • Microsoft.EntityFrameworkCore.Sqlite

模型类

通过 EF Core 访问的 SQLite 数据库中的每个表都在某个类中进行建模。 在本例中使用了两个类 - BlogPost,它们位于 Models 文件夹。

模型类仅由属性(在数据库中对列建模)组成。

  • Blog.cs

    using System;
    using System.Collections.Generic;
    
    namespace EFGetStarted
    {
        public class Blog
        {
            public int BlogId { get; set; }
            public string Url { get; set; }
    
            public List<Post> Posts { get; set; } = new List<Post>();
        }
    }
    
  • Posts 属性会定义 BlogPost 之间的父子关系。

  • Post.cs

    using System;
    namespace EFGetStarted
    {
        public class Post
        {
            public int PostId { get; set; }
            public string Title { get; set; }
            public string Content { get; set; }
    
            public int BlogId { get; set; }
            public Blog Blog { get; set; }
        }
    }
    
  • BlogIdBlog 属性与 Post 的实例的父级 Blog 对象相关联。

数据上下文

BloggingContext 类位于 Services 文件夹中,并继承自 EF Core DbContext 类。 DbContext 用于将数据库查询和更改组合到一起。

using System;
using System.IO;
using Microsoft.EntityFrameworkCore;
using Xamarin.Essentials;

namespace EFGetStarted
{
    public class BloggingContext : DbContext
    {
        public DbSet<Blog> Blogs { get; set; }
        public DbSet<Post> Posts { get; set; }

        public BloggingContext()
        {
            SQLitePCL.Batteries_V2.Init();

            this.Database.EnsureCreated();
        }

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            string dbPath = Path.Combine(FileSystem.AppDataDirectory, "blogs.db3");

            optionsBuilder
                .UseSqlite($"Filename={dbPath}");
        }
    }
}
  • DbSet 类中的两个属性都用于对表示博客和文章的基础表进行操作。
  • 构造函数中需要 SQLitePCL.Batteries_V2.Init() 才能在 iOS 上启动 SQLite。
  • OnConfiguring 函数可在物理设备上设置 SQLite 数据库的位置。

创建、读取、更新和删除

下面是应用中的一些实例,其中 EF Core 用于访问 SQLite。

阅读

  • 返回所有记录。
    • BlogsPage.xaml.csOnAppearing 函数可返回所有 Blog 记录,并将它们存储在 List 变量中。
using (var blogContext = new BloggingContext())
{
    var theBlogs = blogContext.Blogs.ToList();
}
  • 返回特定记录。
    • PostsPage.xaml.csOnAppearing 函数可返回包含特定 BlogIdPost 记录。
using (var blogContext = new BloggingContext())
{
    var postList = blogContext.Posts
        .Where(p => p.BlogId == BlogId)
        .ToList();
}

创建​​

  • 插入新记录。
    • AddBlogPage.xaml.csSave_Clicked 函数可将新的 Blog 对象插入到 SQLite 数据库中。
var blog = new Blog { Url = blogUrl.Text };

using (var blogContext = new BloggingContext())
{
    blogContext.Add(blog);

    await blogContext.SaveChangesAsync();
}

Update

  • 更新现有记录。
    • AddPostPage.xaml.csSave_Clicked 函数使用新的 Post 更新现有的 Blog 对象。
var newPost = new Post
{
    BlogId = BlogId,
    Content = postCell.Text,
    Title = titleCell.Text
};

using (var blogContext = new BloggingContext())
{
    var blog = await blogContext
        .Blogs
        .FirstAsync(b => b.BlogId == BlogId);

    blog.Posts.Add(newPost);

    await blogContext.SaveChangesAsync();
}

删除

  • 删除所有记录并级联删除其子记录。
    • BlogsPage.xaml.csDeleteAll_Clicked 函数可删除 SQLite 数据库中的所有 Blog 记录,并级联删除 Blog 的所有 Post 子记录。
using (var blogContext = new BloggingContext())
{
    blogContext.RemoveRange(blogContext.Blogs);

    await blogContext.SaveChangesAsync();
}

后续步骤

在本入门教程中,你已了解如何使用 Xamarin.Forms 应用程序通过 Entity Framework Core 访问 SQLite 数据库。

Xamarin 开发人员感兴趣的其他 Entity Framework Core 主题: