Entity Framework Core 在执行第一个查询时速度很慢

问题描述 投票:0回答:1

我是第一次使用 Entity Framework Core,当我试图理解为什么每次启动项目时执行第一个查询时速度太慢(大约 2-3 秒)时,我感到非常困惑。

为了给您提供额外信息,我可以说我正在开发一个 .NET 6 项目,.NET 框架的版本是 7.0.18,因为它是与我的 .NET 版本兼容的最后一个版本。

这是我调用来执行查询的方法:

public async Task<string> GetField()
{
    using ContextClass context = new ContextClass();

    var variable = await context.Table
                        .FirstOrDefaultAsync(v => v.Id == 429719);

    return variable?.Field ?? "a"; //If nothing is found, it will retrieve an empty string
}

我可以看到的是,如果我调用相同的方法(或从另一个方法调用另一个方法

DataContext
),它将不会再花费这些秒,并且结果将立即返回。

我目前找到的解决方案是创建一个“初始化器”类,它执行以下操作:

public class Initializer
{
    public Initializer() { }

    public async void DbInitializer()
    {
        using (var context = new CodisContext())
        {
            await context.Database.EnsureCreatedAsync();
        }
    }
}

调用

DbInitializer
函数使第一个查询按预期运行。

您有任何提示或建议来避免使用此方法吗?

c# entity-framework-core .net-6.0
1个回答
0
投票

针对 DbContext 的第一个查询将需要等待 EF 初始化其模型。 DbContext 越大、越复杂,花费的时间就越长。对于 Web 应用程序,只要应用程序池回收,就会发生这种情况,其中可能包括将站点设置为在空闲时保留资源的情况。 (空闲超时)

类似初始化程序的东西,或者只是执行一个简单的查询,例如:

using var context = new CodisContext();
context.Table.Any();

...当您的应用程序池启动时足以触发首次运行预热成本。 (即就在

app.Run()
之前)

或者,如果您有一个大型、复杂的模式可供使用,您可以考虑将其拆分为较小的有界 DbContext,其中每个 DbContext 负责应用程序中的一个关键区域。如果较小的上下文不需要完整的信息,则可以使用表格的简化表示,这样可以更简单、更快速地使用。

对于从实体返回单个字段或字段子集,利用投影来构建高效的查询。您的示例可能只是一个简单的演示查询,但如果您的代码只想从一条或多条记录中检索一些信息:

var variable = await context.Table
    .Where(v => v.Id == id)
    .Select(v => v.Field)
    .FirstOrDefaultAsync(); 

return variable ?? DefaultValue;

您的示例与上面的示例之间的区别在于,在您的情况下,当您只关心一列时,您将执行查询以从数据库中检索整个记录。该实体也将不必要地添加到 EF 的跟踪缓存中。仅应在您想要更新实体的地方执行此操作,以便您可以更改该实体并调用

SaveChanges()
让 EF 构建适当的
UPDATE
语句。对于简单的读取操作,上面的查询将仅构建一个 SQL 语句来检索单个所需的列(如果找到)。在具有许多潜在大列的较大表上,这可以在性能和资源使用方面产生非常明显的差异。

© www.soinside.com 2019 - 2024. All rights reserved.