c# - 在 Entity Framework 4.1 版本中使用 Code-First 时性能极慢

标签 c# entity-framework-4.1

我们公司正在开发一个新的应用程序,它的核心是一个比较大的业务数据对象。我们决定先用代码尝试 Entity Framework ,以从应用程序中抽象出数据库,但事情出了差错。业务对象由大约 60 个类组成,总共大约 600 个属性;然而,它是一个树结构,不存在交叉/回溯指针。

我们的测试是向数据库添加一个未初始化的类实例。在我们的数据结构上使用 DbContext.Add 在我的开发机器上花费了 8 分钟。这是这种大小的物体的预期性能吗?是否有导致 Entity Framework 性能不佳的常见问题列表?我觉得我需要一些帮助。

一些更多的数据点:业务对象根下的第一层有 27 个元素。存在 3 个元素(其余元素已注释掉),添加时间为 4.5 秒。存在 5 个元素时,它是 11.8 秒。有 8 个元素存在,它是 1 分 12.5 秒。显然,这些元素的大小差异很大,但这似乎表明存在某种系统性问题。

最佳答案

...Our test was to add a single, uninitialized instance of the class to the database. Using DbContext.Add...

您是否确保在调用Add 之前创建了您的代码优先模型并将其加载到内存中?我的意思是:如果你使用这样的测试代码......

using (var context = new MyContext())
{
    var myHugeBusinessObject = CreateItSomeHow();

    context.HugeBusinessObjects.Add(myHugeBusinessObject);

    context.SaveChanges();
}

...这是您第一次在测试应用程序中使用上下文 Add 在开始将对象添加到上下文。

您可以通过在调用 Add 之前添加一个虚拟方法来简单地将这两个步骤分开,例如:

context.HugeBusinessObjects.Count();

我已经构建了一个测试:

public class MyClass
{
    public int Id { get; set; }
    public string P1 { get; set; }
    // ... P2 to P49
    public string P50 { get; set; }
    public MyClass Child1 { get; set; }
    // ... Child1 to Child26
    public MyClass Child27 { get; set; }
}

我用这个创建了一个对象:

var my = new MyClass();
MyClass child = my;
for (int i = 0; i < 100; i++)
{
    child.Child1 = new MyClass();
    child = child.Child1;
}
child = my;
for (int i = 0; i < 100; i++)
{
    child.Child2 = new MyClass();
    child = child.Child2;
}
// and so on up to Child27

所以这个对象图有 2700 个子对象,每个子对象有 50 个标量属性。然后我测试了这段代码:

using (var context = new MyContext())
{
    var my = CreateWithTheCodeAbove();

    context.MyClassSet.Count();
    context.MyClassSet.Add(my);

    context.SaveChanges();
}

...Count()(= 构建 EF 模型)大约需要 25 秒添加 需要1 秒。 (在上面的循环中将 100 更改为 1000(然后图表中有 27000 个对象)将 Add 的时间几乎线性增加到 9-10 秒。)此结果独立于设置 AutoDetectChangesEnabledtruefalse。)

下一个有趣的结果:如果我将 20 个导航属性(Child28Child47)添加到 MyClass 构建模型所花费的时间(示例代码中的 Count())爆炸到 140 秒Add 的持续时间仅随附加属性线性增加。

因此,我的假设是:您实际上测量的不是将业务对象添加到上下文的时间,而是 EF 在内存中构建 EF 模型所需的时间。构建模型的时间似乎随着模型的复杂性呈指数增长:一个类的导航属性数量,可能还有不同涉及类的数量。

要像上面建议的那样用一些虚拟调用来分隔这些步骤测试。如果你已经有了这种分离……天哪,忘记这篇文章吧。

关于c# - 在 Entity Framework 4.1 版本中使用 Code-First 时性能极慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6989582/

相关文章:

.net - 模型验证 : Retrieving all rules registered by Entity Framework 4. 1

entity-framework - 使用 Entry<TEntity>().CurrentValues.SetValues() 不会更新集合

c# - 调用 C++/CLI 包装器时出现外部异常 E0434352

c# - 在编辑模式下重新填充级联下拉列表 - MVC

c# - Entity Framework POCO 长期变更跟踪

c# - Entity Framework 代码优先与 T4 模板

c# - .Net MVC 实体和 ViewModel...相同还是独立?

c# - 在 ASP.NET 网站中使用 Dll

c# - 我如何在 C# 中获取一年前的今天日​​期?

asp.net - 为什么我想将 UnitOfWork 与存储库模式一起使用?