【发布时间】:2013-05-02 18:24:02
【问题描述】:
我从 DbSet.Find() 调用中获得了糟糕的性能。我的代码如下所示:
public class Area
{
[Key]
public string Id { get; protected set; }
// ...
}
public class MyContext : DbContext
{
//...
public DbSet<Area> Areas { get; set; }
//...
}
// This is the call that takes so long
Area area = context.Areas.Find(id);
我知道这必须搜索实体集,检查更改跟踪等,并将触发对数据库的调用。问题是它比简单的context.Areas.SingleOrDefault(x => x.Id == id) 调用要长几个数量级。比我认为合理的要多得多。根据另一个问题的提示,我还尝试暂时关闭更改跟踪但没有成功(它似乎没有任何效果):
try
{
context.Configuration.AutoDetectChangesEnabled = false;
return context.Areas.Find(id);
}
finally
{
context.Configuration.AutoDetectChangesEnabled = true;
}
为了尝试找出问题的根源,我启动了我的分析器。这是我发现的:
看起来它一直在花时间准备执行计划。但是为什么在.Find() 调用期间需要这么长时间而不是显式的.SingleOrDefault 调用(请注意,在调用堆栈的顶部附近,它实际上正在准备SingleOrDefault 调用)。有什么方法可以查看.Find() 方法实际上正在尝试编译的查询?
【问题讨论】:
-
你的 Area 类的完整代码吗? ti 是从其他类继承的吗?
-
@jure - 几乎。显然还有一些其他属性和几种方法,但大多数情况下它是一个非常简单的实体类。
-
您展示的图片仅占查询的 6%(我假设所有这 6% 的总和超过 100 个)。 Area 是否引用了许多其他实体?延迟加载是否被禁用,因此是否加载所有关联?问题可能是您的操作正在加载一个 large 相关的对象图。
-
@qujck - 6% 超过了应用程序被分析的总时间,其中包括另外 94% 的其他活动。关于配置文件屏幕截图需要注意的重要事项是 1) 顶部的 Find() 在绝对时间方面花费了太长的时间,以及 2) Find() 调用中花费的大部分时间都在 Compile( ) 进一步调用堆栈。关于您的问题 - 该实体没有任何参考资料。有可能 Find() 调用也试图加载一些其他内容 - 我将尝试处理它最终发送的确切查询。
标签: c# .net entity-framework linq-to-entities