EFCore-实体跟踪
EFCore-实体跟踪
EFCore实现了直接对实体类对象进行操作可以直接影响表中数据
将实体类和数据表绑定的更加紧密了
实体跟踪
在实体类和数据表建立关系那一刻,EFCore就会将该实体标记并且跟踪
实体类
在DbContext中注册的DbSet在调用时有五种状态
- 已添加(Added):DbContext正在跟踪此实体,但数据库中还没存在
- 未改变(Unchanged):DbContext正在跟踪此实体,该实体存在于数据库中,其属性值和从数据库中得到的值一致,未发生改变
- 已修改(Modified):DbContext正在跟踪此实体,并存在与数据库中,并且其部分或全部属性值已修改
- 已删除(Deleted):DbContext正在跟踪此实体,并存在与数据库中,但下次调用SaveChanges时要从数据库中删除对应数据
- 已分离(Detached):DbContext未跟踪该实体
在SaveChanges()的时候,根据实体状态的不同,生成Update、Delete、Insert等SQL语句,来将内存中实体的变化推送到数据库中
AsNoTracking
基于这种跟踪机制,微软会使用内存来持续跟踪,这无疑是占用了一部分内存的
我们可以手动让其不跟踪实体,在进行查询的时候,这种方式是一种对资源不错的优化
但要进行增删改操作,就不能让其不跟踪,否则实体类修改后表中数据不会改变
批量的增删改
模型驱动的EFCore的LINQ语法更适合去进行数据库查询,而面对批量增删改的时候并不是很好用
但EFCore7.0版本之后已经增加了高效批量操作的方法:
- ExecuteUpdateAsync
- ExecuteDeleteAsync
需要注意的是,执行这两个方法的时候,EFCore是不会对实体进行状态跟踪的
杨中科提供了一个自己写的框架,可以用EFCore对数据进行批量操作
导入依赖
Zack.EFCore.Batch.Npgsql_NET6
软删除
在之前的Java项目中,已经接触过很多次软删除的概念了
在EFCore中,我们可以通过全局查询筛选器来添加一个查询条件
在每次查询的时候,都将这个查询条件加在SQL中,就能筛选掉“被删除”的数据库
public class DBContext : DbContext
{
public DbSet<Article> Articles { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Article>(entity =>
{
entity.ToTable("Articles");
// 配置全局查询过滤器,将Is_Deleted == 0 作为查询条件
entity.HasQueryFilter(a => a.Is_Deleted == 0);
});
}
}
查看已删除的数据
调用IgnoreQueryFilters忽略掉全局过滤器,在手动添加条件为Is_Deleted == 0的查询条件
using (var dbContext = new DBContext())
{
dbContext.Articles.IgnoreQueryFilters().Where(a => a.Is_Deleted == 1);
}