C# 为什么第一次使用实体框架调用数据库会花费更长的时间,即使之前已经调用过该数据库?

C# 为什么第一次使用实体框架调用数据库会花费更长的时间,即使之前已经调用过该数据库?,c#,entity-framework,ms-access,C#,Entity Framework,Ms Access,我正在使用实体框架从Access数据库获取数据。我发现了这样一个场景:我使用三种不同的查询调用数据库。不管我如何组织它们,第一个总是需要2到3秒,其余的调用在几毫秒内执行。下面是一个小例子: var myData1 = await myRepo.GetData1(); var myData2 = await myRepo.GetData2(); var myData3 = await myRepo.GetData3(); 在这种情况下,myRepo.GetData1()需要2-3秒。剩下的代码

我正在使用实体框架从Access数据库获取数据。我发现了这样一个场景:我使用三种不同的查询调用数据库。不管我如何组织它们,第一个总是需要2到3秒,其余的调用在几毫秒内执行。下面是一个小例子:

var myData1 = await myRepo.GetData1();
var myData2 = await myRepo.GetData2();
var myData3 = await myRepo.GetData3();
在这种情况下,
myRepo.GetData1()
需要2-3秒。剩下的代码运行得非常快。如果我重新排列它们并首先调用
myRepo.GetData2()
,那么这一次将需要2-3秒,并且
myRepo.GetData1()
将运行得非常快

起初我以为这是第一次访问这个数据库,但调试后我意识到这个数据库连接以前已经打开过

是否有我缺少的配置



编辑:进一步调试后,连接看起来在几秒钟后“重置”。因此,在这个块之后,如果我在2秒后查询同一个DB,返回数据再次需要2-3秒!是否有办法保持连接“活动”?

在流程中第一次引用DbContext定义时,实体框架DbContext会有一个预热成本。此预热用于解决所有已配置的映射,实际上与建立DB连接没有多大关系

当应用程序首次启动时,您可以启动一个简单、快速的查询来启动预热,例如:

var result = _context.Users.Any();

这可以作为预热加上验证数据库连接是否可用。初始化是静态的,因此新确定范围的dbcontext(例如每个会话或使用块在
中确定范围)不会产生额外的预热成本。如果定义了多个DBContext(即有界DbContext,则即使指向同一数据库,也需要对每个定义进行预热。

初始化DbContext会有第一次的成本,特别是当您有许多数据库时tables@ErikEJ这也是我的第一个猜测。但是这个数据库以前被访问过。那么这不意味着它已经被访问过了吗?DbContext已经初始化了吗是的,我在这之前从数据库中获取了数据。如果要将该查询添加到
IHostedService
,http管道将在所有托管服务启动之前不会处理请求。这是让我困惑的部分。我在这一点之前已经查询了数据库。进一步调试后,连接看起来像是“重置”了几秒钟后。因此,在此块之后,如果我在2秒钟后查询相同的数据库,则再次需要2-3秒钟才能返回数据!是否有方法保持连接“活动”?这是符合您的标记的MS Access数据库吗?可能是该提供程序需要的某些行为或配置,或者特定实现中的某些其他细节。(您使用的是EDMX还是EntityTypeConfiguration等?)对于SQL Server或PostreSQL之类的提供程序,当使用DbContext的第一个实例时,只需要1倍的加速成本。如果您看到同一个DbContext多次出现这种情况,则可能会提示其他情况。当释放DbContext时,连接通常会被释放。这是正常的,通常是需要的行为。一种选择可能是通过类似DbContextFactory之类的东西使用手动连接处理程序:MS访问和EF连接管理可能比其他提供商更昂贵?(在使用手动连接之前,我希望在代码/配置中消除其他可能的罪魁祸首)