C # DbConnection приведен к SqlConnection - PullRequest
16 голосов
/ 05 сентября 2010

Я нашел этот кусок кода в одном приложении

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

Безопасно ли, SqlConnection получено из DbConnection. База данных взята из Microsoft.Practices.EnterpriseLibrary.Data. Согласно документации CreteDatabase возвращает DbConnection.

Ответы [ 4 ]

13 голосов
/ 05 сентября 2010

Нет, это небезопасно, приведение никогда не безопасно, и оно может взорваться в любое время, когда ваше приложение работает.* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Даже за то, что 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-запросов и приведение от одного поставщика базы данных к другому.Но для простого приложения это нормально.

10 голосов
/ 05 сентября 2010

Это должно быть безопасно, если вы никогда не измените строку подключения для подключения к чему-либо, кроме базы данных SQL Server. Если это когда-либо возможно, тогда вам нужно добавить немного больше логики, чтобы сделать вещи безопаснее:

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

using(DbConnection conn = database.CreateConnection())
{    
    if(conn is SqlConnection)
    {
        var sqlConn = conn as SqlConnection;
    }
}
5 голосов
/ 05 сентября 2010

Это зависит от баз данных, которые вы используете в вашем приложении.Из написанного вами кода похоже, что используется только SQL Server.Если это так, то вы можете безопасно разыграть DbConnection до SqlConnection.Фактически DbConnection является базовым классом для любого другого соединения с базой данных.В вашем случае это SqlConnection (который используется для работы с SQL Server базой данных), также существуют разные базы данных, такие как Oracle, Mysql и т. Д., И их провайдеры обычно имеют собственные классы для соединений.Поэтому, если ваше приложение использует другие базы данных или может использовать его в будущем, такое преобразование небезопасно.

1 голос
/ 24 марта 2019

Вы всегда можете выполнить проверку и преобразовать ее в SqlConnection с сопоставлением с шаблоном C # (C # 7.0 +)

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");
    }
}
...