当数据仅仅只是做查询不修改的情况下,尤其是数据量还不小的情况下,使用可以减少内存的消耗
var u2 = await ctx.Users.AsNoTracking().Take(3).ToListAsync();
如果使用了AsNoTracking()之后下面对对象进行了修改,调用SaveChangesAsync()并不会对数据库的数据进行修改。
//先查询 在修改 实际是执行了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不支持高效的删除,更新,插入数据,都是逐条操作AddRange、DeleteRange等
微软计划EF Core7 会有此功能大约在2022.11 对应今年的Net7在同月发布
sqlBulkCopy(批量操作)
微软官方issue
Zack.EFCore.Batch nuget包 支持批量操作
使用场景: 逻辑删除数据(软删除)、多租户
//在对应的实体的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); }
注意事项:
使用全局筛选器之后,根据具体项目的实际情况,可能会影响性能,到时候需要自己来对筛选条件的字段添加索引,不一定会产生性能问题。但是如果产生,这是一个解决方向。