首页 > 解决方案 > 如何为 EF Core 中的单个查询设置命令超时?

问题描述

我知道可以使用该context.Database.SetCommandTimeout方法设置命令超时。但这会更改使用同一DbContext实例进行的所有查询的超时。

我知道我可以设置超时,运行查询并重置超时,但这感觉就像一个黑客。我想为每个查询设置超时。类似于如何SqlCommand.CommandTimeout在 ADO.NET 中为每个查询设置。是否可以使用 EF Core 做到这一点?

标签: c#entity-frameworkasp.net-coreentity-framework-core

解决方案


正如我在评论中所说,这不是我认为必要或真正有用的东西。我已经调试了一些 EF Core 的代码(使用 VS 2019 很容易,通过让它从 nuget 服务器加载符号或强制它反编译为源代码)。我们可以调用一些“插入点”,您可以在其中注入一些东西来修改SetCommandTimeout单个查询。例如对于 LINQ 查询

public class MyCommandInterceptor : DbCommandInterceptor
{
    public override InterceptionResult<DbDataReader> ReaderExecuting(DbCommand command, CommandEventData eventData, InterceptionResult<DbDataReader> result)
    {
        return base.ReaderExecuting(command, eventData, result);
    }
}

带着

.AddInterceptors(new MyCommandInterceptor()); 

把你配置你DBContext的地方可能是最好的地方。当拦截器运行时,DbCommand command已经有了标准Timeout集,您可以更改它。问题显然是设置您想要的超时并将此信息传递给拦截器。这很复杂,我不确定是否有好的解决方案(我认为有各种丑陋的解决方案......在查询构建期间添加信息并让拦截器知道这些信息似乎很困难)

如果您有兴趣,将DbCommand创建于Microsoft.EntityFrameworkCore.Storage.CreateDbCommand().

如果您想要预先打包的东西,则响应是否定的,什么都没有。您显然可以自由地将其推荐为efcore github中的功能。如果修改 EF 的源代码,添加这个功能会相对容易。


推荐阅读