【问题标题】:Creating DbCommand does get timeout assigned from DBContext创建 DbCommand 确实会从 DBContext 分配超时
【发布时间】:2019-11-08 19:49:10
【问题描述】:

我有使用 EF Core 的 ASP.NET Core 2.2 应用程序。在 startup.cs 我将 CommandTimeout 设置为 60 秒

services.AddDbContext<CrowdReason.WMP.Data.Entities.WMPContext>(options => 
   options.UseSqlServer(configuration.GetConnectionString("DefaultConnection"),
                  sqlServerOptions => sqlServerOptions.CommandTimeout(60)));

然后我正在使用以下代码执行存储过程。请注意 cmets 中 t1t2t3 的值

    public static async Task<int?> prcDoWork(this WMPContext dbContext, int id, int userID)
    {
        var t1 = dbContext.Database.GetCommandTimeout();            
        // t1 is 60. Same as what i set in startup.cs

        using (var connection = dbContext.Database.GetDbConnection())
        {
            var t2 = connection.ConnectionTimeout;                                
            //t2 is 15

            using (var cmd = connection.CreateCommand())
            {                    
                var p1 = new SqlParameter("@ID", SqlDbType.Int)
                {
                    Value = id
                };
                var p2 = new SqlParameter("@UserID", SqlDbType.Int)
                {
                    Value = userID
                };
                cmd.CommandText = "dbo.prcDoWork";
                cmd.CommandType = CommandType.StoredProcedure;
                cmd.Parameters.Add(p1);
                cmd.Parameters.Add(p2);

                var t3 = cmd.CommandTimeout;
                //t3 is 30

                await dbContext.Database.OpenConnectionAsync().ConfigureAwait(false);
                var result = await cmd.ExecuteScalarAsync().ConfigureAwait(false);
                if (result != null)
                {
                    return Convert.ToInt32(result);
                }

                return null;
            }
        }
    }

我了解ConnectionTimeoutCommandTimeout 不同。 但是问题是当我使用connection.CreateCommand() 创建命令时,它不会自动从 DBContext 获取超时

【问题讨论】:

    标签: ef-core-2.0 ef-core-2.1 ef-core-2.2


    【解决方案1】:

    EF Core 在底层 System.Data 实现(在您的情况下为 System.Data.SqlClient)之上工作,并使用它来执行其数据库操作。您所做的所有设置将仅反映 EF 使用此底层实现的方式。

    当您使用 GetDbConnection 方法时,您会从 System.Data.SqlClient 程序集中获得对 SqlConnection 类的引用,该类对 EF 及其设置一无所知,并且不能期望遵循来自 Microsoft.EntityFrameworkCore.RelationalRelationalOptionsExtension.CommandTimeout组装。

    要尊重 EF 设置,您应该使用 RelationalDatabaseFacadeExtensions.ExecuteSqlCommandAsync 方法。

    【讨论】:

      猜你喜欢
      • 2021-05-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-04
      • 1970-01-01
      • 2019-11-15
      • 1970-01-01
      • 2014-05-10
      • 2020-11-26
      相关资源
      最近更新 更多