Entity Framework Core 入门

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

可以在 Windows 或 Visual Studio for Mac 上使用 Visual Studio 来学习本教程。

提示

可以在 GitHub 上查看本文的示例。

先决条件

安装以下项之一:

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

下载并运行示例项目

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

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

首次启动应用时,它将使用表示博客的两个条目填充本地 SQLite 数据库。

所有博客列表页面 的屏幕截图

单击工具栏中的 添加 按钮。

将显示一个新页面,用于输入有关新博客的信息。

新博客编辑页面 的屏幕截图

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

可以单击列表中的其中一个博客条目,并查看该博客的任何文章。

博客文章列表页面 的屏幕截图

单击工具栏中的 添加

然后会显示一个页面,用于填写有关新博客文章的信息。

添加新帖子页面 的屏幕截图

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

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

返回到博客列表页。 然后单击 删除工具栏中的所有。 然后,将从应用的 SQLite 数据库中删除所有博客及其相应的文章。

屏幕截图:应用 中所有博客已被删除

浏览代码

以下部分将引导你完成示例项目中的代码,该代码使用 EF Core 和 Xamarin.Forms 从 SQLite 数据库读取、创建、更新和删除数据。

假设你熟悉 Xamarin.Forms 的主题:数据展示 和页面间导航

重要

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

  • 第一个是将 --linkskip System.Core 添加到 其他 mtouch 参数 中的 iOS 生成 选项。
  • 或者,将 Xamarin.iOS 链接器 的行为设置为 Don't Link 后,在 iOS 构建 选项中进行调整。 本文详细介绍了 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();
      }
      
  • 返回特定记录。

    • OnAppearing 函数在 PostsPage.xaml.cs 中返回包含特定 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();
      }
      

更新

  • 更新现有记录。
    • Save_Clicked 函数在 AddPostPage.xaml.cs 中使用新的 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();
      }
      

删除

  • 删除包含级联到子记录的所有记录。
    • DeleteAll_Clicked 函数 BlogsPage.xaml.cs 删除 SQLite 数据库中的所有 Blog 记录,并将该删除操作级联到所有 BlogPost 记录。

      using (var blogContext = new BloggingContext())
      {
          blogContext.RemoveRange(blogContext.Blogs);
      
          await blogContext.SaveChangesAsync();
      }
      

后续步骤

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