【问题标题】:Why are these Add/.Modify operations in Entity Framework so slow?为什么 Entity Framework 中的这些 Add/.Modify 操作这么慢?
【发布时间】:2015-10-15 09:53:56
【问题描述】:

在一些用户抱怨速度慢之后,我一直在用探查器查看 WCF 应用程序中的性能瓶颈。

令我惊讶的是,几乎所有问题都归结为实体框架操作。我们使用存储库模式,大多数“添加/修改”代码看起来非常像这样:

public void Thing_Add(Thing thing)
{
    Log.Trace("Thing_Add called with ThingID " + thing.ThingID);

    if (db.Things.Any(m => m.ThingID == thing.ThingID))
    {
        db.Entry(thing).State = System.Data.EntityState.Modified;
    }
    else
    {
        db.Things.Add(thing);
    }
}

这显然是将添加/更新检查包装到单个函数中的便捷方式。

现在,我知道 EF 在进行插入和更新时并不是最有效的方法。但是,我的理解是(一项小研究证实了这一点)它应该能够比用户可能注意到的速度更快地处理数百条记录。

但这对小型 upsert 造成了很大的瓶颈。例如,在一种情况下,处理大约 50 条记录需要 6 秒钟。这是一个特别糟糕的例子,但似乎在整个应用程序中都有一些实例,即小型 EF upsert 需要一两秒以上的时间。肯定足以惹恼用户。

我们将 Entity Framework 5 与 Database First 模型一起使用。探查器说导致问题的不是 Log.Trace。这可能是什么原因造成的,我该如何调查和解决这个问题?

【问题讨论】:

  • 6秒在什么环境下?调试?发布?从二进制运行?我问是因为我注意到 EF 在调试时运行异常缓慢,但在编译后的二进制文件中却运行良好。
  • @GrahamBass 已发布。在调试模式下运行速度一样慢。
  • 我不知道这是否有帮助,但是如果已经附加了“事物”,则无需将状态设置为已修改。所以如果你在实际上没有改变的事情上调用这个代码,你就是在浪费时间。您可以在将状态设置为已修改之前检查状态是否已分离。
  • 另外,您是否在每次调用此方法后调用 SaveChanges()?或者只是一个 SaveChanges() 如果你调用它一次结果会好得多。另外(可能是一个愚蠢的问题)但是数据库中的 ThingId 字段是否有索引/主键?
  • 你有 varchar 列吗?我曾多次遇到的一个可能的问题是,如果 where 子句实体框架中有一个 varchar 列,默认情况下将参数化为 nvarchar,从而导致该列显式类型转换为 nvarchar 并忽略索引。 stackoverflow.com/questions/15767803/… 我建议运行 sql profiler 以查看数据库级别的实际情况。

标签: c# entity-framework wcf


【解决方案1】:

我在另一个 SO 帖子中找到了问题的根源:DbContext is very slow when adding and deleting

事实证明,当您处理大量对象时,尤其是在循环中,更改跟踪的逐渐积累会使 EF 变得越来越慢。

在这种情况下刷新 DbContext 是不够的,因为我们仍在处理太多的链接实体。所以我把它放在存储库中:

public void AutoDetectChangesEnabled(bool detectChanges)
{
    db.Configuration.AutoDetectChangesEnabled = detectChanges;
}

现在可以使用它在执行循环插入之前打开和关闭 AutoDetectChangesEnabled:

try
{
    rep.AutoDetectChangesEnabled(false);
    foreach (var thing in thingsInFile)
    {
        rep.Thing_add(new Thing(thing));
    }
}
finally
{
    rep.AutoDetectChangesEnabled(true);
}

这真是天壤之别。虽然它需要小心使用,因为它会阻止 EF 识别对已更改对象的潜在更新。

【讨论】:

    猜你喜欢
    • 2016-04-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-26
    相关资源
    最近更新 更多