Entity Framework Core-DbContext

Entity Framework Core DbContext 是一个非常重要的类,通过它来维持与数据库之间的会话,因此它可以执行数据库操作,例如 新增,修改,删除,查询数据,我们可以通过继承 DbContext 类创建一个数据库的 ContextDbContext 可以完成如下工作:.

1.管理数据库链接

2.配置实体关系映射

3.数据库查询,新增,修改,删除数据

4.配置变化跟踪

5.缓存

6.事务管理

1 EF Core 例子

我们创建一个 Entity Framework Core 例子项目理解如何使用 DBContext 类工作,创建一个 ASP.NET Core MVC 的项目,我们把项目命名为 EFCoreDbContext,接下来安装数据库对应的 Provider,使用下面命令安装最新版本的包:
Install-Package Microsoft.EntityFrameworkCore.SqlServer
我们也可以在上面命令后面指定版本号,说明安装指定的版本
Install-Package Microsoft.EntityFrameworkCore.SqlServer -Version 7.0.4

我们也可以使用.NET CLI 安装相应的包

dotnet add package Microsoft.EntityFrameworkCore.SqlServer --version 7.0.4
可以通过查看 NuGet 官网查看对应的命令以及版本号https://w
ww.nuget.org/packages/Microsoft.EntityFrameworkCore.S
qlServer/这个项目中我们数据库只有 2 张表:

1.Department – 部门信息表

2.Employee – 员工信息表

创建 2 个实体和这两张表做映射,在项目 Models 文件夹下创建 Department & Empl oyee 类,类代码如下:

namespaceEFCoreDbContext.Models{    publicclassDepartment    {        publicint Id { get; set; }        publicstring Name { get; set; }        public ICollection<Employee> Employee { get; set; }    }}
namespaceEFCoreDbContext.Models{    publicclassEmployee    {        publicint Id { get; set; }        publicint DepartmentId { get; set; }        publicstring Name { get; set; }        publicstring Designation { get; set; }        public Department Department { get; set; }    }}
Employee 属性在 Department 类和Department 属性,Employee 
类是分别承担导航属性作用,导航属性表示具体引用的类,Department & Employee 是一对多的关系
2 创建 DbContext 类

我们在应用程序的 Models 文件夹内创建一个 CompanyContext 类并且继承自 DbContext 类,该类在 Microsoft.EntityFrame

workCore 命名空间,添加一个构造函数,并且调用基类的构造
namespaceEFCoreDbContext.Models{    publicclassCompanyContext : DbContext    {        public CompanyContext(DbContextOptions<CompanyContext> options)                      : base(options)        {        }    }}
接下来我们添加 2 个 DbSet 属性,这将告诉 EF Core 两件事:
1.这些实体匹配数据库中对应的表
2.这些实体匹配表中对应的行

DbSet表示实体的集合,是对实体执行数据库操作的入口Company

Context 类定义如下:
namespaceEFCoreDbContext.Models{    publicclassCompanyContext : DbContext    {        public CompanyContext(DbContextOptions<CompanyContext> options)                      : base(options)        {        }        public DbSet<Department> Departments { get; set; }        public DbSet<Employee> Employees { get; set; }    }}
2.1 OnModelCreating() 方法
DbContext 类 OnModelCreating()方法承担以下职责:
1.属性是否是必须
2.实体属性长度
3.实体关系,一对多,一对一等
在 CompanyContext 中添加 OnModelCreating 方法
namespaceEFCoreDbContext.Models{    publicclassCompanyContext : DbContext    {        public CompanyContext(DbContextOptions<CompanyContext> options)                      : base(options)        {        }        public DbSet<Department> Departments { get; set; }        public DbSet<Employee> Employees { get; set; }        protected override void OnModelCreating(ModelBuilder modelBuilder)        {            modelBuilder.Entity<Department>(entity =>            {                entity.Property(e => e.Name)                .IsRequired()                .HasMaxLength(50)                .IsUnicode(false);            });            modelBuilder.Entity<Employee>(entity =>            {                entity.Property(e => e.Designation)                .IsRequired()                .HasMaxLength(25)                .IsUnicode(false);                  entity.Property(e => e.Name)                .IsRequired()                .HasMaxLength(100)                .IsUnicode(false);                  entity.HasOne(e => e.Department)                .WithMany(p => p.Employee)                .HasForeignKey(d => d.DepartmentId)                .OnDelete(DeleteBehavior.ClientSetNull)                .HasConstraintName("FK_Employee_Department");            });        }    }}

我们已经配置了 Department 和 Employee 实体类,我们通过使用 IsRequired 方法确保字段是必填项,类似的使用 HasMaxLength(100)方法设置 employee 类属性的最大长度,代码使用外键设置实体的一对多关系

.HasForeignKey(d => d.DepartmentId).OnDelete(DeleteBehavior.ClientSetNull).HasConstraintName("FK_Employee_Department");

2.2 注册 DBContext

using EFCoreExample.Models;using Microsoft.EntityFrameworkCore;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddDbContext<CompanyContext>(options =>  options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection")));// Add services to the container.builder.Services.AddControllersWithViews();
var app = builder.Build();.....

2.3 配置数据库链接字符串

我们将数据库链接字符串存储到项目配置文件appsettings.json,因此添加数据库链接字符串

{ "ConnectionStrings": {    "DefaultConnection": "Server=(localdb)\\MSSQLLocalDB;Database=EFCoreDbContext;Trusted_Connection=True;MultipleActiveResultSets=true"  }}
2.4 运行 EF Core Migrations
我们根据定义的实体类使用 Migrations 创建数据库,在运行 Migrations 之前请确保你已经安装了 Microsoft.EntityFrame
workCore.Tools 在 Package Manager Console 窗体运行下面 2 个命令:

2.4.1 Add Migration Command

add-migration Migration1
这个命令会在我们项目目录下创建一个新的 Migrations 文件夹,在该文件夹下创建 2 个.cs 文件,如下图显示:

Entity Framework Core-DbContext

2.4.2 Update Migration Command

运行下面命令,使用 Migration 文件夹下生成的 CS 文件创建我们的数据库
 Update-Database

 2.5 DbContext 方法

现在我们检查一下 SQL Server 发现数据库已经被创建,EF Core DbContext 有一些重要的方法:

名称 描述
Add 使用 Added 状态添加一个实
AddRange Add 的批量版本
Attach 使用该方法会将实体设置为 Unchanged 状态
AttachRange Attach 的批量版本
Remove 将实体状态设置为 deleted 状态
RemoveRange Remove 的批量版本
Update 设置实体被跟踪并且修改实体状态为 Modified,并且会跟踪关联实体,如果该实体关联一个集合,会导致每一个实体生成一个 update 语句,如果对应实体主键没有值,将会设置为 Added 状态,生成对应的 insert 语句
UpdateRange Update 的批量版本
SaveChanges 将实体中使用了 Added、Modified、Deleted 状态的数据执行对应的 INSERT、UPDATE、DELETE 操作并将其更新到数据库中

2.5.1 测试

现在我们测试一下是否能正常工作,我们使用 EF Core 插入一条记录,我们在 HomeController 中添加如下代码:

using EFCoreExample.Models;using Microsoft.AspNetCore.Mvc;using Microsoft.EntityFrameworkCore;
namespaceEFCoreExample.Controllers{    publicclassHomeController : Controller    {        private CompanyContext context;        public HomeController(CompanyContext cc)        {            context = cc;        }
        public IActionResult Index()        {            var dept = new Department()            {                Name = "Designing"            };            context.Entry(dept).State = EntityState.Added;            context.SaveChanges();
            return View();        }    }}
首先我们控制器的构造函数中添加一个数据库上下文的依赖,由于我们在 Program 类中注册了 DbContext 服务,所以我们可以使用依赖注入技术获取到该对象
private CompanyContext context;public HomeController(CompanyContext cc){    context = cc;}
我们使用 EF Core 在数据库中创建一条新的记录
var dept = new Department(){    Name = "Designing"};context.Entry(dept).State = EntityState.Added;context.SaveChanges();

运行应用程序并在浏览器中初始化这个方法这将在数据库 Depart

ment 表中插入一条新的记录,打开表发现一条新的记录被添加,如下图所示

Entity Framework Core-DbContext

3 OnConfiguring()方法
DbContext 类的 OnConfiguring()方法用来配置 EF Core 数据源,在 CompanyContext 类中添加这个方法,我们使用 DbContextOption sBuilder 类的 UseSqlServer()提供数据库字符串链接
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder){    if (!optionsBuilder.IsConfigured)    {        optionsBuilder.UseSqlServer(@"Server=vaio;Database=Company;Trusted_Connection=True;");    }}
在实际的生产过程中我们一般不使用上面这种方式添加链接字符串
总结
这一节中我们主要介绍了EFCore DbContext可以帮助我们从数据库中创建、修改、读取、删除记录
源代码地址:
https://github.com/bingbing-gui/Asp.Net-Core-Skill/tree/master/EntityFrameworkCore/EFCoreDbContext