EF Core 优化、实体状态跟踪、批量操作、全局查询筛选器

EF Core 优化之AsNoTracking

当数据仅仅只是做查询不修改的情况下,尤其是数据量还不小的情况下,使用可以减少内存的消耗

var u2 = await ctx.Users.AsNoTracking().Take(3).ToListAsync(); 
注意:

如果使用了AsNoTracking()之后下面对对象进行了修改,调用SaveChangesAsync()并不会对数据库的数据进行修改。

EF Core 实体状态跟踪的妙用
//先查询 在修改 实际是执行了2次sql语句
var book = await ctx.Books.FirstAsync();
book.Price = 101;
ctx.SaveChanges();

//下面只执行了一次sql语句
Book b1 = new Book { Title = "标题" + 10086, PubTime = DateTime.UtcNow, Price = 101, AuthorName = "firstsaofan" + 10086 };//此处状态是已分离
var entry1 = ctx.Entry(b1);
entry1.Property("Price").IsModified = true;
ctx.SaveChanges();

//直接删除这条记录
Book b3 = new Book { Id = 2 };
ctx.Entry(b3).State = EntityState.Deleted;
ctx.SaveChanges();

总结:

上述代码能看懂即可,不推荐使用,由此带来的性能提升很微弱,使用不当,弊大于利。仅作了解

EF Core 批量插入,更新,删除(2022.07.27)

此时EF Core不支持高效的删除,更新,插入数据,都是逐条操作AddRange、DeleteRange等

微软计划EF Core7 会有此功能大约在2022.11 对应今年的Net7在同月发布

sqlBulkCopy(批量操作)

微软官方issue

Zack.EFCore.Batch nuget包 支持批量操作

EF Core全局查询筛选器

使用场景: 逻辑删除数据(软删除)、多租户

//在对应的实体的config类文件里面的config方法加上
builder.HasQueryFilter(e => e.IsDeleted == false);
//之后所有的查询默认都会加上这个条件
//如果在特定不需要全局筛选器 使用IgnoreQueryFilters()即可
foreach (var item in ctx.Books.IgnoreQueryFilters().Where(b => b.AuthorName.Contains("fir"))) 
{
    Console.WriteLine(item.Id+item.Title);
}

注意事项:

使用全局筛选器之后,根据具体项目的实际情况,可能会影响性能,到时候需要自己来对筛选条件的字段添加索引,不一定会产生性能问题。但是如果产生,这是一个解决方向。