带有不完整的ConnectionString的Open()方法中的System.Data.SqlClient.SqlConnection意外结果

时间:2018-12-04 16:33:31

标签: c# sqlconnection

在传递了不完整的连接字符串的Open()实例上调用SqlConnection方法时,该方法不会引发异常。

我创建了以下示例来展示我的问题。

var success = true;

var connectionStrings = new[]
        {
            "Integrated Security=SSPI;",
            "Initial Catalog=awdemo;Integrated Security=SSPI;",
            "Data Source=.\\sql2016;Initial Catalog=awdemo;Integrated Security=SSPI;"
};

foreach (var connectionString in connectionStrings)
{
    var conn = new SqlConnection(connectionString);

    try
    {
         conn.Open();
    }
    catch (Exception)
    {
        success = false;
    }
    finally
    {
        conn.Close();
        Console.WriteLine($"{connectionString} - Success = {success}");
    }
}

结果:

Integrated Security=SSPI; - Success = True
Initial Catalog=awdemo;Integrated Security=SSPI; - Success = True
Data Source=.\sql2016;Initial Catalog=awdemo;Integrated Security=SSPI; - Success = True

我希望conn.Open()会为前两个连接字符串引发异常,因为它们都不完整且无效。

为什么没有抛出异常?

编辑:正如史蒂夫(Steve)在评论中指出的那样,未引发异常,因为该组件在不提供服务器信息时会连接到我的默认SQL Server实例。

是否有一种方法可以强制SqlConnection组件在不完整的连接字符串上引发错误?在该应用程序中,可以并允许创建不完整的连接字符串。

1 个答案:

答案 0 :(得分:1)

没有实际方法可以完全验证这一点。您可能具有一个连接字符串,其中包含所需的所有组件,包括有效的服务器和数据库名称,但这是错误的服务器或错误的数据库。

因此,如果期望的是如果连接字符串不正确(不是无效,而是不正确),则类应该在conn.Open()上失败,那么您将无法完全实现。

有关系吗?想象一下几种情况,所有情况都包含错误的连接字符串:

  1. 连接字符串为“ blarg!”。因此尝试打开连接会引发异常。
  2. 连接字符串不包含服务器或数据库名称。您可以打开连接,但尝试执行某些命令时会失败。
  3. 连接字符串包含服务器和数据库名称,但它是错误的服务器或数据库。失败的原因与2相同。

在每种情况下,您要做的第一件事是什么?您将要查看异常。无论哪一行抛出,您都将迅速得出错误的连接字符串。

因此,“验证”实际上无法在打开连接字符串之前对其进行验证,这只会增加工作量。如果连接字符串是错误的,那确实是一个“例外”条件,因此最好让代码在发生异常的地方抛出异常。您会很快发现问题。

除此之外,假设您真的想确保在尝试打开连接之前,连接中包含服务器名和数据库名。您可以编写这样的扩展方法:

// Maybe give it a better name.
public static void ValidateThatConnectionHasDataSourceAndDatabase(this SqlConnection connection)
{
    if (string.IsNullOrEmpty(connection.DataSource)) 
        throw new Exception("The connection has no datasource");
    if (string.IsNullOrEmpty(connection.Database)) 
        throw new Exception("The connection has no database");
}

在创建连接之后并打开它之前,请致电conn.ValidateThatConnectionHasDataSourceAndDatabase();