跳转至

使用 DbContext

Working with DbContext in EF Core

We created our entities and DbContext class in the previous chapters. Here you will learn the overview of working with the DbContext to create a database and interact with it using EF Core 7 on .NET 7 platform.

在前面的章节中,我们创建了实体和 DbContext 类。在这里,你将了解使用 DbContext 创建数据库以及在 .NET 7 平台上使用 EF Core 7 与其交互的概述。

The following is our .NET 7 console project along with entities and a context (SchoolDbContext) class.

以下是我们的 .NET 7 控制台项目,以及实体和一个上下文类(SchoolDbContext)。

![[Pasted image 20250413194157.png]]

EF Core Sample Project

EF Core 示例项目

The following are Student and Grade classes.

以下是 StudentGrade 类。

public class Student
{
    public int StudentId { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }

    public int GradeId { get; set; }
    public Grade Grade { get; set; }
}

public class Grade
{
     public Grade()
     {
         Students = new List<Student>();
     }

    public int GradeId { get; set; }
    public string GradeName { get; set; }

    public IList<Student> Students { get; set; }
}

The following is our context class SchoolDbContext created in the Create DbContext chapter.

以下是我们在[[Create DbContext_20250324084458|Create DbContext]]章节中创建的上下文类 SchoolDbContext

public class SchoolContext : DbContext
{       
    //entities
    public DbSet<Student> Students { get; set; }
    public DbSet<Grade> Grades { get; set; }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseSqlServer("Server=(localdb)\\mssqllocaldb;Database=SchoolDb;Trusted_Connection=True;");
    }
} 

The above context class includes two DbSet<TEntity> properties, for Student and Grade, type which will be mapped to the Students and Grades tables in the underlying database. In the OnConfiguring() method, an instance of DbContextOptionsBuilder is used to specify a database connection string.

上述上下文类包含两个 DbSet<TEntity> 属性,分别对应 StudentGrade 类型,这些类型将被映射到底层数据库中的 StudentsGrades 表。在 OnConfiguring() 方法中,使用 DbContextOptionsBuilder 的实例来指定数据库连接字符串。

Database Schema Creation in EF Core

EF Core 中的数据库架构创建

After creating the context and entity classes, it's time to start interacting with our underlying database using the context class. However, before we save or retrieve data from the database, we first need to ensure that the database schema is created as per our entities and configurations.

在创建上下文和实体类后,接下来是使用上下文类与底层数据库进行交互。不过,在从数据库中保存或检索数据之前,我们需要确保数据库架构根据我们的实体和配置创建完成

There are two ways using which you can create a database and schema:

  1. Using the EnsureCreated() method
  2. Using Migration API

有两种方法可以创建数据库和架构:

  1. 使用 EnsureCreated() 方法
  2. 使用迁移 API

Creating a database using the EnsureCreated() method is common to use following by EnsureDeleted() method when testing or prototyping using Entity Framework Core framework.

在使用 Entity Framework Core 框架进行测试或原型开发时,通常会在调用 EnsureDeleted() 方法后使用 EnsureCreated() 方法来创建数据库

Migrations API allows you to create an initial database schema based on your entities and then as and when you add/delete/modify your entities and config, it will sync to the corresponding schema changes to your database so that it remains compatible with your EF Core model (entities and other configurations).

迁移 API 允许您基于实体类创建初始数据库架构,随后当您对实体和配置进行增删改操作时,它会将对应的架构变更同步到数据库,从而保持数据库与 EF Core 模型(实体及其他配置)的兼容性

Let's use the EnsureCreated() method to create a database and use the context class to save student and grade data in the database.

让我们使用 EnsureCreated() 方法创建数据库,并通过上下文类将学生和班级数据保存至数据库中。

using EFCoreTutorialsConsole;

using (var context = new SchoolDbContext())
{
    //creates db if not exists 
    context.Database.EnsureCreated();

    //create entity objects
    var grd1 = new Grade() { GradeName = "1st Grade" };
    var std1 = new Student() {  FirstName = "Yash", LastName = "Malhotra", Grade = grd1};

    //add entitiy to the context
    context.Students.Add(std1);

    //save data to the database tables
    context.SaveChanges();

    //retrieve all the students from the database
    foreach (var s in context.Students) {
        Console.WriteLine($"First Name: {s.FirstName}, Last Name: {s.LastName}");
    }
}

Let's understand the above example code:

让我们来理解上述示例代码:

  • The using(){ .. } statement creates a scope for a SchoolDbContext instance called context. It ensures that the context is properly disposed of when it's no longer needed.
  • using(){ .. } 语句为一个名为 context 的 SchoolDbContext 实例创建了一个作用域。它确保在不再需要该上下文时,能够正确释放资源。
  • The context.Database.EnsureCreated(); statement checks if the database exists. If it doesn't exist, it creates the database based on the entity classes defined as DbSet<TEntity> properties in the SchoolDbContext class. This is a simple way to create the database schema based on your entity model.
  • context.Database.EnsureCreated(); 语句检查数据库是否存在。如果数据库不存在,它将根据在 SchoolDbContext 类中定义为 DbSet<TEntity> 属性的实体类创建数据库。这是一种根据实体模型简单创建数据库架构的方法。
  • Next, two entity objects are created: grd1 of type Grade and std1 of type Student. These objects are entity objects that represent records in the database.
  • 接下来,创建了两个实体对象:类型为 Gradegrd1 和类型为 Studentstd1。这些对象是表示数据库中记录的实体对象。
  • The std1 student entity is added to the Students property of the context. It also assigns grd1 to its Grade property. This prepares the Student entity to be saved to the database along with the Grade entity.
  • std1 学生实体被添加到上下文的 Students 属性中。同时,将 grd1 赋值给它的 Grade 属性。这为将 Student 实体和 Grade 实体一起保存到数据库做好了准备。
  • The context.SaveChanges(); is called to persist the changes to the database. It effectively inserts a new student record into the "Students" table and a new grade record into the "Grades" table.
  • 调用 context.SaveChanges(); 以将更改持久化到数据库中。这实际上在 "Students" 表中插入了一条新的学生记录,并在 "Grades" 表中插入了一条新的成绩记录。
  • After saving changes, a foreach loop retrieves all the students from the "Students" table in the database using the context.Students property. It then prints the first name and last name of each student to the console.
  • 在保存更改后,使用 context.Students 属性通过 foreach 循环从数据库的 "Students" 表中检索所有学生。然后将每个学生的名字和姓氏打印到控制台上。

Now, run the project by pressing Ctrl + F5. It will display the following output.

现在,通过按 Ctrl + F5 运行项目。它将显示以下输出。

![[Pasted image 20250413194333.png]]

As you can see, it displays the output. EF Core API has created the "SchoolDB" database and inserted records in the "Students" and "Grades" tables. You can see that in the SQL Server Explorer in your visual studio from View -> SQL Server Object Explorer. If it is not connected to your local db then click on the + sign to connect to your db, as shown below.

如您所见,它显示了输出。EF Core API 创建了 "SchoolDB" 数据库,并在 "Students" 和 "Grades" 表中插入了记录。您可以在 Visual Studio 的视图菜单 -> SQL Server 对象资源管理器中查看到这一点。如果没有连接到您的本地数据库,请点击 + 符号以连接到您的数据库,如下所示。

![[Pasted image 20250413194339.png]]

In the popup, select "MSSQLLocalDB" and click on the "Connect" button, as shown below.

在弹出窗口中,选择 "MSSQLLocalDB",然后点击 "连接" 按钮,如下所示。

![[Pasted image 20250413194353.png]]

Now, you can see the database, as shown below.

现在,您可以看到数据库,如下所示。

![[Pasted image 20250413194400.png]]

Expand (localdb) > Database > SchoolDB node in SQL Server Object Explorer. You can also see tables and their columns by expanding it further, as shown below.

在 SQL Server 对象资源管理器中展开 (localdb) > 数据库 > SchoolDB 节点。您还可以通过进一步展开它来查看表及其列,如下所示。

![[Pasted image 20250413194404.png]]

To see the records, right-click on the table name and click "View Data". It will display records in Visual Studio as below.

要查看记录,右键单击表名,然后点击“查看数据”。它将在 Visual Studio 中显示记录,如下所示。

![[Pasted image 20250413194410.png]]

In this way, we have successfully used EF Core API to save and retrieve data to the SQL Server database. Visit Saving Data and Querying chapters to learn more about saving and retrieving data in EF Core.

通过这种方式,我们成功使用 EF Core API 将数据保存到 SQL Server 数据库并检索数据。请访问 保存数据查询 章节,以了解更多关于在 EF Core 中保存和检索数据的信息。

The EnsureCreated() method does not modify the schema if the database exists and has any tables. Nothing is done to ensure the database schema is compatible with the Entity Framework model. So it is mainly for the testing in clean db. Use Migration API for the development.

EnsureCreated() 方法如果数据库存在并且有任何表,就不会修改架构。它不会做任何事情来确保数据库架构与实体框架模型兼容。因此,这主要用于在干净的数据库中进行测试。在开发中使用迁移 API。


参考链接:

<% tp.file.cursor(3) %>