C# .NET EFCore 性能优化
查询缓存优化
利用EF Core的查询缓存机制,相同的查询语句会被缓存,避免重复编译。对于频繁执行的查询,可以显式启用缓存:
var compiledQuery = EF.CompileQuery((DbContext context, int id) => context.Products.FirstOrDefault(p => p.Id == id));
批量操作处理
使用AddRange
或RemoveRange
替代单条操作,结合SaveChanges
的批处理能力:
context.Products.AddRange(productList);
context.SaveChanges();
启用批处理需要配置SQL Server提供程序:
optionsBuilder.UseSqlServer(connectionString, o => o.MaxBatchSize(100));
延迟加载慎用
导航属性的延迟加载会导致N+1查询问题。显式加载或预加载更高效:
var orders = context.Orders.Include(o => o.OrderDetails).ToList();
异步操作提升吞吐量
使用async/await
避免线程阻塞:
var product = await context.Products.FirstOrDefaultAsync(p => p.Id == id);
跟踪行为控制
只读查询禁用变更跟踪:
var products = context.Products.AsNoTracking().Where(p => p.Price > 100).ToList();
索引优化
确保查询字段有数据库索引:
modelBuilder.Entity<Product>().HasIndex(p => p.CategoryId);
SQL日志监控
开发阶段开启日志检查生成SQL:
optionsBuilder.UseLoggerFactory(loggerFactory).EnableSensitiveDataLogging();
分页查询优化
使用Skip
/Take
时确保有序:
var pagedData = context.Products.OrderBy(p => p.Id).Skip(20).Take(10).ToList();
原始SQL复杂查询
高性能场景直接执行SQL:
var products = context.Products.FromSqlRaw("SELECT * FROM Products WITH (NOLOCK)").ToList();
连接池配置
调整DbContext池大小避免资源争用:
services.AddDbContextPool<AppDbContext>(options => options.UseSqlServer(connectionString), poolSize: 128);