我们公司正在开发一个新的应用程序,它的核心是一个比较大的业务数据对象。我们决定先用代码尝试 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 秒。)此结果独立于设置 AutoDetectChangesEnabled
为 true
或 false
。)
下一个有趣的结果:如果我将 20 个导航属性(Child28
到 Child47
)添加到 MyClass
构建模型所花费的时间(示例代码中的 Count()
)爆炸到 140 秒。 Add
的持续时间仅随附加属性线性增加。
因此,我的假设是:您实际上测量的不是将业务对象添加到上下文的时间,而是 EF 在内存中构建 EF 模型所需的时间。构建模型的时间似乎随着模型的复杂性呈指数增长:一个类的导航属性数量,可能还有不同涉及类的数量。
要像上面建议的那样用一些虚拟调用来分隔这些步骤测试。如果你已经有了这种分离……天哪,忘记这篇文章吧。
关于c# - 在 Entity Framework 4.1 版本中使用 Code-First 时性能极慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6989582/