繁体   English   中英

SqlConnection 有什么问题?

[英]What's wrong with the SqlConnection?

我有一个代码来检查是否已经部署了具有某个指定名称的存储过程。 代码是

protected virtual async Task<bool?> IsProcedureDeployed(string storedProcedureName)
        {
            try
            {
                SqlCommand sqlCommand = new SqlCommand
                {
                    CommandText = "select count(*) from sysobjects where type = 'P' and name = @storedProcedureName",
                    CommandType = CommandType.Text,
                    CommandTimeout = this.CommandTimeout
                };

                await this.EnsureConnectionOpened();
                int count = (int)(await sqlCommand.ExecuteScalarAsync());

                return count > 0;
            }
            catch (Exception exception)
            {
                this.SqlConnection.Close();
                ExceptionDispatchInfo.Capture(exception).Throw();
                return null;
            }
        }

this.EnsureConnectionOpened 看起来像这样:

protected async Task EnsureConnectionOpened()
        {
            if (SqlConnection.State == ConnectionState.Closed && SqlTransaction == null)
            {
                await SqlConnection.OpenAsync();
            }
        }

当涉及到执行int count = (int)(await sqlCommand.ExecuteScalarAsync()); 它总是抛出一个异常,上面写着......“无效的操作。连接已关闭。”。 我检查了SqlConnection的状态,它是Open! 我到底做错了什么?

编辑。 每个 SqlCommand 都必须有一个 SqlConnection 和正确设置的参数(如果需要)。 最终版本是

protected virtual async Task<bool?> IsProcedureDeployed(string storedProcedureName)
        {
            try
            {
                SqlCommand sqlCommand = new SqlCommand("select count(*) from sysobjects where type = 'P' and name = @storedProcedureName", this.SqlConnection)
                {
                    CommandType = CommandType.Text,
                    CommandTimeout = this.CommandTimeout
                };

                SqlParameter sqlParameter = new SqlParameter
                {
                    ParameterName = "@storedProcedureName",
                    Value = storedProcedureName
                };

                sqlCommand.Parameters.Add(sqlParameter);

                await this.EnsureConnectionOpened();
                int count = (int)(await sqlCommand.ExecuteScalarAsync());

                return count > 0;
            }
            catch (Exception exception)
            {
                this.SqlConnection.Close();
                ExceptionDispatchInfo.Capture(exception).Throw();
                return null;
            }
        }

我会稍微修改一下这个方法。 将所有连接的东西放在同一个地方,而不是散布在各个地方。 此外,由于您发布的代码仅使用 try/catch 关闭连接(并重新抛出异常),因此我将其完全删除。 这里不需要任何错误处理。 让异常发生并冒泡到调用方法。 我猜这个逻辑在你的数据层?

像这样的东西被包含得很好很整洁。

protected virtual async Task<bool?> IsProcedureDeployed(string storedProcedureName)
{
    bool IsDeployed = false;
    using (var conn = new SqlConnection(ConfigurationManager.ConnectionStrings["YourConnectionString"].ConnectionString))
    {
        conn.Open();
        using (var cmd = new SqlCommand("select count(*) from sysobjects where type = 'P' and name = @storedProcedureName", conn))
        {
            cmd.Parameters.Add("@storedProcedureName", SqlDbType.NVarChar, 128).Value = storedProcedureName; //using nvarchar(128) because object names use sysname which is a synonym for nvarchar(128)
            var result = await cmd.ExecuteScalarAsync();
            bool.TryParse(result.ToString(), out IsDeployed);
        }
    }
    return IsDeployed;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM