EF Core 命令超时未生效

Den*_*er9 5 c# entity-framework command-timeout entity-framework-core

我发现该DatabaseFacade.SetCommandTimeout方法和该SqlServerDbContextOptionsBuilder.CommandTimeout方法都对我的代码没有任何影响,而是长时间运行的 SQL 命令只是无限期地继续。

我的上下文对象看起来像这样:

public class MyDataContext : DbContext
{
    public MyDataContext()
    {
        base.Database.SetCommandTimeout(60);
    }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) 
    {
        ...
        optionsBuilder.UseSqlServer(connection, sqlServerOptions => sqlServerOptions.CommandTimeout(60));
    }
}
Run Code Online (Sandbox Code Playgroud)

但是当我在 Web API 中执行代码时:


using var dbContext = new MyDataContext();
var timeout = dbContext.Database.GetCommandTimeout(); // this, as expected, returns "60"
var listOfEntities = dbContext.MyLargeSetOfEntities.ToList(); // this, however, just runs way longer than a minute (it is returning an immense amount of data to test the timeout)

Run Code Online (Sandbox Code Playgroud)

是否有什么地方可以覆盖这个值并使其不确定?

Iva*_*oev 6

该值没有被覆盖,但您对它的作用有错误的期望。

它返回大量数据来测试超时

命令超时仅适用于数据库命令的ExecuteXYZ部分,这对于查询来说是,即限制执行 SQL 查询的时间(想象一些具有许多连接、笛卡尔积、分组依据、子查询等的超级复杂 SQL 命令。需要永远运行。或者某些访问的表被另一个长时间运行的事务锁定等)。ExecuteReader

一旦执行了 SQL 命令,消费结果(在本例中是读取返回的数据)就不受任何限制——只是没有这样的设置,也不可能有这样的设置。

如果您想限制整个操作的时间,请考虑将命令超时设置与异步取消支持相结合,例如在异步方法中

var listOfEntities = await dbContext.MyLargeSetOfEntities
    .ToListAsync(new CancellationTokenSource(TimeSpan.FromSeconds(60)).Token);
Run Code Online (Sandbox Code Playgroud)