实体框架第一次查询由于跳过符号而变慢

本文关键字:符号 于跳过 框架 第一次 查询 实体 | 更新日期: 2023-09-27 18:02:35

我知道第一个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()都相当慢。

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

这可能吗?还是有办法加快速度?

谢谢。

实体框架第一次查询由于跳过符号而变慢

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

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

建议阅读:Performance Considerations (Entity Framework)