由于跳过符号,实体框架首先查询缓慢

时间:2014-05-10 09:08:23

标签: c# entity-framework

我知道第一个EF查询缓慢的问题已经讨论过了,但没有一个答案似乎适合。

当我第一次运行EF查询时,执行需要3到5秒。当我再次运行它时,它只需要几毫秒。

测试代码:

Stopwatch sw = new Stopwatch();

Console.WriteLine("--- CONNECTION ---");
sw.Restart();
Context = new Connection();
sw.Stop();
Console.WriteLine("Elapsed time in seconds: " + sw.Elapsed.ToString(@"s\.ffff"));

Console.WriteLine("--- FIRST QUERY ---");
sw.Restart();
Context.Set<T>().Count();
sw.Stop();
Console.WriteLine("Elapsed time in seconds: " + sw.Elapsed.ToString(@"s\.ffff"));

Console.WriteLine("--- SECOND QUERY ---");
sw.Restart();
Context.Set<T>().Count();
sw.Stop();
Console.WriteLine("Elapsed time in seconds: " + sw.Elapsed.ToString(@"s\.ffff"));

控制台输出:

--- CONNECTION ---
'Shell.vshost.exe' (Managé (v4.0.30319)) : 'D:\Developpement\CSharp_Prism\Test_Prism_2\Prism\src\Shell\bin\Debug\System.Data.SQLite.EF6.dll' chargé
'Shell.vshost.exe' (Managé (v4.0.30319)) : 'D:\Developpement\CSharp_Prism\Test_Prism_2\Prism\src\Shell\bin\Debug\System.Data.SQLite.dll' chargé
'Shell.vshost.exe' (Managé (v4.0.30319)) : 'D:\Developpement\CSharp_Prism\Test_Prism_2\Prism\src\Shell\bin\Debug\EntityFramework.SqlServer.dll' chargé
'Shell.vshost.exe' (Managé (v4.0.30319)) : 'C:\Windows\Microsoft.Net\assembly\GAC_64\System.Transactions\v4.0_4.0.0.0__b77a5c561934e089\System.Transactions.dll' chargé, chargement des symboles ignoré. Le module est optimisé et l'option du débogueur 'Uniquement mon code' est activée.
Elapsed time in seconds: 0.2727

--- FIRST QUERY ---
'Shell.vshost.exe' (Managé (v4.0.30319)) : 'C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Numerics\v4.0_4.0.0.0__b77a5c561934e089\System.Numerics.dll' chargé, chargement des symboles ignoré. Le module est optimisé et l'option du débogueur 'Uniquement mon code' est activée.
'Shell.vshost.exe' (Managé (v4.0.30319)) : 'C:\Windows\Microsoft.Net\assembly\GAC_64\System.Data.OracleClient\v4.0_4.0.0.0__b77a5c561934e089\System.Data.OracleClient.dll' chargé, chargement des symboles ignoré. Le module est optimisé et l'option du débogueur 'Uniquement mon code' est activée.
Native library pre-loader is trying to load native SQLite library "D:\Developpement\CSharp_Prism\Test_Prism_2\Prism\src\Shell\bin\Debug\x64\SQLite.Interop.dll"...
'Shell.vshost.exe' (Managé (v4.0.30319)) : 'C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Data.Entity\v4.0_4.0.0.0__b77a5c561934e089\System.Data.Entity.dll' chargé, chargement des symboles ignoré. Le module est optimisé et l'option du débogueur 'Uniquement mon code' est activée.
'Shell.vshost.exe' (Managé (v4.0.30319)) : 'C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Xml.resources\v4.0_4.0.0.0_fr_b77a5c561934e089\System.Xml.resources.dll' chargé
'Shell.vshost.exe' (Managé (v4.0.30319)) : 'C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Dynamic\v4.0_4.0.0.0__b03f5f7f11d50a3a\System.Dynamic.dll' chargé, chargement des symboles ignoré. Le module est optimisé et l'option du débogueur 'Uniquement mon code' est activée.
'Shell.vshost.exe' (Managé (v4.0.30319)) : 'C:\Windows\Microsoft.Net\assembly\GAC_64\System.EnterpriseServices\v4.0_4.0.0.0__b03f5f7f11d50a3a\System.EnterpriseServices.dll' chargé, chargement des symboles ignoré. Le module est optimisé et l'option du débogueur 'Uniquement mon code' est activée.
'Shell.vshost.exe' (Managé (v4.0.30319)) : 'C:\Windows\Microsoft.Net\assembly\GAC_64\System.EnterpriseServices\v4.0_4.0.0.0__b03f5f7f11d50a3a\System.EnterpriseServices.Wrapper.dll' chargé, chargement des symboles ignoré. Le module est optimisé et l'option du débogueur 'Uniquement mon code' est activée.
'Shell.vshost.exe' (Managé (v4.0.30319)) : 'D:\Developpement\CSharp_Prism\Test_Prism_2\Prism\src\Shell\bin\Debug\fr\EntityFramework.resources.dll' chargé
Elapsed time in seconds: 3.3032

--- SECOND QUERY ---
Elapsed time in seconds: 0.0035

是的,这是法国人,对不起。基本上,这是“跳过加载符号”消息。

程序集列表会根据我使用的查询而更改:Context.Set<T>()不会加载任何内容并且非常快。 Context.Set<T>().Count()Context.Set<T>().ToList()都很慢。

我不确定这些消息到底意味着什么(如果跳过加载为什么还需要时间?),但如果我必须加载一些程序集,我宁愿在启动时这样做。

这可能吗?或者有办法加快速度吗?

感谢。

1 个答案:

答案 0 :(得分:2)

Context.Set<T>()不加载任何内容,因为这是查询定义,而不是查询执行。 Count()ToList()方法都强制查询执行(即查询将转换为在数据库上执行的SQL)。

第一个查询总是会执行得更慢,因为EF需要加载元数据(它使用xml或代码映射)。

建议阅读:Performance Considerations (Entity Framework)