C#中的DbConnection如何转换为SqlConnection?

24

我在一个应用程序中发现了这段代码

Database database = DatabaseFactory.CreateDatabase("connection string");
DbConnection connection = database.CreateConnection();
connection.Open();
SqlConnection sqlConnection = (SqlConnection)connection;

SqlConnection是从DbConnection派生而来的,Database来自Microsoft.Practices.EnterpriseLibrary.Data。根据文档,CreateDatabase返回DbConnection。

4个回答

18
不,这不安全。转换类型从来都不安全,并且在你的应用程序运行时可能会随时出现问题。虽然 SqlConnection 确实是从 DbConnection 派生而来,但是不能保证 database.CreateConnection() 会返回一个 SqlConnection,因为它可以在配置文件中进行参数化。另外,为什么需要转换成 SqlConnection?最好使用更高层次的类来避免将代码与特定实现耦合在一起,否则将使您的代码无法在隔离环境下测试。
虽然 EnterpriseLibrary 在保持抽象方面做得相当不错,但您的转换操作却破坏了所有规则。此外,您应该确保可处置资源始终得到适当的处理。那么,不如尝试这个方案:
Database database = DatabaseFactory.CreateDatabase("connection string");
using (var conn = database.CreateConnection())
using (var cmd = conn.CreateCommand())
{
    conn.Open();
    cmd.CommandText = "SELECT id FROM foo";
    using (var reader = cmd.ExecuteReader())
    {
        while (reader.Read())
        {
            // TODO: work with the results here
        }
    }
}

这样,你的代码就不那么容易受到配置文件中数据库更改的影响了。当然,你仍然必须硬编码SQL,而且还有ORM可以处理这种情况。它们还允许您专注于应用程序的真正领域,而不是在编写SQL查询和将其从一个数据库提供程序转换为另一个方面浪费时间。但对于简单的应用程序来说,这是可以的。


这段代码中使用了一个需要 SqlConnection 作为参数的方法。 - Darqer

11

只要你从不将连接字符串更改为连接到除SQL Server数据库之外的任何其他内容,就应该是安全的。 如果这可能成为实际情况,那么您应该添加一些逻辑以确保安全:

Database database = DatabaseFactory.CreateDatabase("conn string");

using(DbConnection conn = database.CreateConnection())
{    
    if(conn is SqlConnection)
    {
        var sqlConn = conn as SqlConnection;
    }
}

没有太大的区别,使用不带'is'的'as',然后检查是否为空更有效率。 - Mark Lakata

6

这取决于您在应用程序中使用的数据库。从您编写的代码中看来,似乎只使用了 SQL Server。如果是这样,那么您可以安全地将 DbConnection 强制转换为 SqlConnection。实际上,DbConnection 是任何其他数据库连接的基类。在您的情况下,它是 SqlConnection(用于处理 SQL Server 数据库),还有不同的数据库,如 OracleMysql 等,它们的提供程序通常具有自己的连接类。因此,如果您的应用程序使用另一个数据库或未来可能使用,则进行此类强制转换是不安全的。


2
它不仅取决于所使用的数据库,更直接地取决于工厂基于使用的数据库返回的类型。如果他们决定创建一个新的连接类来使用SQL Server,那么代码可能会失败。 - Rune FS

0

您可以始终进行检查并使用C#模式匹配(C# 7.0+)将其转换为SqlConnection

Database database = DatabaseFactory.CreateDatabase("conn string");

using(DbConnection connection = database.CreateConnection())
{    
    if(connection is SqlConnection sqlConnection)
    {
        // do something with sqlConnection
    }
    else
    {
       throw new InvalidOperationException("Connection is not to a SQL Database");
    }
}

这是模式匹配的一个很好的例子,但在这种特定情况下使用它是一种不好的编码实践。 - Bryan Rayner

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接