我知道第一个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()
都很慢。
我不确定这些消息到底意味着什么(如果跳过加载为什么还需要时间?),但如果我必须加载一些程序集,我宁愿在启动时这样做。
这可能吗?或者有办法加快速度吗?
感谢。
答案 0 :(得分:2)
Context.Set<T>()
不加载任何内容,因为这是查询定义,而不是查询执行。 Count()
和ToList()
方法都强制查询执行(即查询将转换为在数据库上执行的SQL)。
第一个查询总是会执行得更慢,因为EF需要加载元数据(它使用xml或代码映射)。