【Entity Framework】 EF中DbContext类详解
一、概述
DbContext类是实体框架的重要组成部分。它是应用域或实例类与数据库交互的桥梁。
从上图可以看出DbContext是负责与数据交互作为对象的主要类。DbContext负责以下活动:
- EntitySet:DbContext包含映射到数据库表的所有实体的实体集(DbSet)。
- 查询(Querying):DbContext将Linq-To-Entities查询转换为SQL查询并将其发送到数据库。
- 更改跟踪(Change Tracking):跟踪实体在从数据库查询后发生的更改
- 持久数据(Persisting Data):它还根据实体的状态对数据库执行插入,更新和删除操作。
- 缓存(Caching): DbContext默认进行一级缓存。它存储在上下文类生命周期中已经被检索的实体。
- 管理关系(Manage Relationship): DbContext还使用DB-First或Model-First方法使用CSDL,MSL和SSDL或者使用Code-First方法使用流利的API来管理关系。
- 对象实现(Object Materialization): DbContext将原始表数据转换为实体对象。
二、DbContext生存期
DbContext
的生存期从创建实例时开始,并在释放实例时结束。DbContext
实例皆在用于单个工作单元。这意味着DbContext
实例的生存期通常很短。
使用Entity Framework Core(EF Core)时的典型工作单元包括:
-
创建
DbContext
实例 -
根据上下文根据实体实例。实体将在以下情况下被追踪
- 正在从查询返回
- 正在添加或附加到上下文中
-
根据需要对所追踪的实体进行更改以实现业务规则
-
调用
SaveChanges
或SaveChangesAsync
。EF Core检测所做的更改,并将这些更改写入数据库。 -
释放
DbContext
实例
三、ASP.NET Core依赖关系注入中的DbContext
在许多Web应用程序中,每个HTTP请求都对应于单个工作单元。这使得上下文生存期与请求的生存期相关,成为Web应用程序的一个良好默认值。
使用依赖关系注入配置ASP.NET Core应用程序。可以使用Startup.cs
的ConfigureServices
方法中的AddDbContext
将EF Core添加到次配置。
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddDbContext<ApplicationDbContext>(
options => options.UseSqlServer("name=ConnectionStrings:DefaultConnection"));
}
此示例将名为 ApplicationDbContext
的 DbContext
子类注册为 ASP.NET Core 应用程序服务提供程序(也称为依赖关系注入容器)中的作用域服务。 上下文配置为使用 SQL Server 数据库提供程序,并将从 ASP.NET Core 配置读取连接字符串。 在 ConfigureServices
中的何处调用 AddDbContext
通常不重要。
ApplicationDbContext
类必须公开具有 DbContextOptions<ApplicationDbContext>
参数的公共构造函数。 这是将 AddDbContext
的上下文配置传递到 DbContext
的方式。 例如:
public class ApplicationDbContext : DbContext
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{
}
}
四、使用"NEW"的简单的DbContext初始化
可以按照常规的 .NET 方式构造 DbContext
实例,例如,使用 C# 中的 new
。 可以通过重写 OnConfiguring
方法或通过将选项传递给构造函数来执行配置。 例如:
public class ApplicationDbContext : DbContext
{
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer(@"Server=(localdb)\mssqllocaldb;Database=Test");
}
}
通过此模式,还可以轻松地通过 DbContext
构造函数传递配置(如连接字符串)。 例如:
public class ApplicationDbContext : DbContext
{
private readonly string _connectionString;
public ApplicationDbContext(string connectionString)
{
_connectionString = connectionString;
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer(_connectionString);
}
}
或者,可以使用DbContextOptionsBuilder
创建DbContextOptions
对象,然后将该对象传递到DbContext
构造函数。这使得为依赖关系注入配置的DbContext
也能显示构造。
public class ApplicationDbContext : DbContext
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{
}
}
五、DbContextOptions
所有 DbContext配置的起始点都是DbContextOptionsBuilder
。可以通过三种方式获取此生成器:
- 在
AddDbContext
和相关方法中 - 在
OnConfiguring
中 - 使用
new
显示构造
上述各节显示了其中每个示例。 无论生成器来自何处,都可以应用相同的配置。 此外,无论如何构造上下文,都将始终调用 OnConfiguring
。 这意味着即使使用 AddDbContext
,OnConfiguring
也可用于执行其他配置。
六、DbContext类的方法
Entry
:获取DbEntityEntry
给定的实体。该条目提供访问更改实体的跟踪信息和操作。
SavaChange
:对已添加,已修改或已删除状态的实体的数据库执行INSERT,UPDATE或DELETE命令。
SaveChangesAsync
: SaveChanges()
的异步方法。
Set
: 创建一个DbSet
可以用来查询和保存实例的TEntity
。