You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

EF6中DbSet.Find方法为何每次都直接查询数据库?

问题分析与解决

你遇到的问题核心是EF6的Find方法缓存匹配失败,明明实体已加载到ObjectStateManager,却仍重复查询数据库,最可能的原因是主键类型不匹配:

关键问题点

你的TestRq实体主键定义为decimal类型:

[Key]
public decimal RQ {get; set;}

但调用Find时传入的是整数类型的3:

testContext.TestRq.Find(3);

EF6在ObjectStateManager中查找实体时,会严格匹配主键的类型——缓存中的实体主键是decimal(3),而你传入的是int类型的3,类型不匹配导致缓存查找失败,每次都会触发数据库查询。

解决方法

将Find的参数改为decimal类型(在数字后加m标识):

using var testContext = new TestContext("Test");
// 用decimal类型的3m作为参数
var testRqFind = testContext.TestRq.Find(3m);
Thread.Sleep(5000);
// 同样传入decimal类型参数
testRqFind = testContext.TestRq.Find(3m);

修改后再次测试,SQL Profiler应该只会出现一次数据库查询,第二次Find会直接返回ObjectStateManager中的缓存实体。

额外排查点(如果上述方法无效)

  • 检查是否意外关闭了实体跟踪:确保没有在DbSet上调用AsNoTracking(),也没有修改testContext.Configuration.AutoDetectChangesEnabled = false(默认是开启状态)
  • 确认实体确实被上下文跟踪:可以在第一次Find后,通过testContext.ChangeTracker.Entries<TestRq>()查看跟踪的实体列表,确认目标实体存在

内容的提问来源于stack exchange,提问作者Leandro Tiraboschi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 22:07:46