实体Context.SaveChanges()在第一次调用时需要更长的时间

时间:2012-04-18 00:12:19

标签: c# entity-framework

当我调用

时,我正在使用带有实体框架的BindingSource
EntityContext.SaveChange();

下次将新对象添加到绑定源然后调用SaveChanges()时,需要更多时间执行。方法

编辑2

详细说明:

在加载表单事件

BindingSource.DataSource = EntityContext.Table;

添加新按钮

BindingSource.AddNew();
Table m_object= (Table)BindingSource.Current;
m_object.ID = Guid.NewGuid();

正在使用绑定到其属性的控件编辑其他对象数据

然后是保存按钮

BindingSource.EndEdit();
Stopwatch sw = new Stopwatch();
sw.Start();
EntityContext.SaveChanges();
sw.Stop();
Console.WriteLine(sw.Elapsed.ToString());

如果我重复添加并保存几次,我会得到以下输出:

00:00:01.0788243

00:00:00.0316786

00:00:00.0292763

00:00:00.0298630

00:00:00.1127312

值得注意的是,第一次添加和保存操作比我下次添加和保存的时间多出几秒钟。

3 个答案:

答案 0 :(得分:1)

这可能有很多原因,一个可能的原因是当您执行第一次提交时,您的数据库是AutoGrowing。您是否有一个正在执行的代码示例以及您观察的时间差异

编辑:

根据您的上述代码,如果数据库中不存在新项目,您可能会创建一个新项目,可能是您第二次单击保存时只是执行更快的SQL内部更新操作吗? (如果EF检测到没有变化,则可能为0次)

答案 1 :(得分:0)

Luke提供的原因是什么,但也不要忘记JIT(即时)编译。当您运行C#应用程序时,它全部编译为MSIL(Microsoft中间语言),当您第一次开始调用方法时,JIT必须将它们编译为本机代码并运行优化以适应其运行的操作系统。这是第一次进行大量操作时的常见原因,可能会有几秒钟的延迟,而不是预期的毫秒数。

Mono具有AOT(提前)编译功能,这意味着它会跳过该步骤并在第一次调用方法时避免额外的时间,但是您在其他地方牺牲了性能。

还有一个工具允许你在Windows上本地预编译C#,但我不记得它的名称。

http://en.wikipedia.org/wiki/Just-in-time_compilation

答案 2 :(得分:0)

另外,不要忘记在第一次操作后可以缓存数据的EF Change Tracker。根据MergeOption和您正在执行的操作,EF可能选择甚至不调用数据库。我将使用SQL事件探查器运行测试,以查看对数据库的实际调用的差异。另外,检查后续调用是否使用相同的数据库连接。