如何验证DbContext未跟踪实体且使用拆分查询?
验证EF Core中拆分查询与无跟踪配置的有效性
我已按如下方式配置DbContext以启用拆分查询:
builder.Services.AddDbContextFactory<NoTrackingDbContext>(options => options.UseSqlServer(config.GetConnectionString("LouisHoweDb"), x => { x.UseNetTopologySuite(); x.UseQuerySplittingBehavior(QuerySplittingBehavior.SplitQuery); }) );
同时设置全局无跟踪行为:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { base.OnConfiguring(optionsBuilder); optionsBuilder.UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking); }
目前我通过查看生成的原始SQL查询、确认查询返回的实体未被上下文跟踪这两种方式验证配置生效,想知道这是不是最佳验证方式?有没有办法通过DbContext的属性直接验证配置?
现有验证方式的合理性
- 查看原始SQL查询:对于拆分查询,EF Core会为关联数据生成多条独立的SELECT语句,这种方式能直观确认拆分行为是否生效,是非常可靠的验证手段。
- 确认实体无附加:通过检查
DbContext.ChangeTracker.Entries()是否为空,或者单个实体的EntityEntry.State是否为Detached,可以直接验证无跟踪配置的效果,同样是有效的验证方法。
通过DbContext属性/API的程序化验证方式
如果需要更自动化的验证(比如在测试用例中),可以直接通过DbContext的相关属性或配置项来检查:
1. 验证拆分查询配置
可以从DbContext的配置选项中提取SqlServer的扩展配置,查看全局拆分查询的设置:
using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.SqlServer.Infrastructure; // 从DbContext实例获取配置 var options = context.Database.GetDbContextOptions(); var sqlServerExtension = options.FindExtension<SqlServerOptionsExtension>(); if (sqlServerExtension?.QuerySplittingBehavior == QuerySplittingBehavior.SplitQuery) { // 全局拆分查询配置已生效 }
2. 验证无跟踪配置
直接访问ChangeTracker的QueryTrackingBehavior属性,即可查看全局跟踪行为设置:
if (context.ChangeTracker.QueryTrackingBehavior == QueryTrackingBehavior.NoTracking) { // 全局无跟踪配置已生效 }
也可以针对单个查询结果验证跟踪状态:
var entity = context.YourEntities.FirstOrDefault(); if (entity != null) { var entry = context.Entry(entity); // 无跟踪配置生效时,State应为Detached bool isNoTracking = entry.State == EntityState.Detached; }
总结
你当前使用的验证方式已经足够直观可靠,适合日常开发中的手动验证;而通过DbContext属性/API的方式则更适合编写自动化测试,确保配置在代码变更后依然符合预期。
内容的提问来源于stack exchange,提问作者David Thielen
相关产品推荐
相关产品推荐

