让数据库连接打开?

时间:2012-10-10 12:48:45

标签: c# sql-server sqlite unit-testing unity-container

我的网络应用程序有以下类:

public class DatabaseProvider {
    private readonly IDbConnection _cn;

    public DatabaseProvider(IDbConnection cn) {
        _cn = cn;
    }

    public void ExecuteNonQuery(string query) {
        // Execute the query
        var cmd = _cn.CreateCommand();
        cmd.CommandText = query;
        cmd.ExecuteNonQuery();
    }
}

使用以下代码(使用Microsoft Unity)声明IDbConnection依赖项:

container.RegisterType<IDbConnection>(new InjectionFactory(c => {
    var cn = new SqlConnection("...");
    cn.Open();
    return cn;
}));

这允许我像这样交换到SQLite的连接:

container.RegisterType<IDbConnection>(new InjectionFactory(c => {
    var cn = new SQLiteConnection("Data Source=:memory:;Version=3;");
    cn.Open();
    return cn;
}));

我在测试时使用SQLite,连接必须保持打开,否则数据会丢失。因此,我不能在需要时打开和关闭连接。

我总是在需要时打开与数据库的连接,并想知道这是否会扩展到大型应用程序?

我很欣赏有关如何改进的建议。感谢

3 个答案:

答案 0 :(得分:5)

作为ADO.NET的一般规则,必须尽快关闭连接。

连接从连接池重用,并且是稀缺资源。

建议的方法是使用using(){}构造。

SQL Server Connection Pooling (ADO.NET)

我们强烈建议您在完成使用后始终关闭连接,以便连接将返回到池。您可以使用Connection对象的Close或Dispose方法,或打开 a C#中的using语句或Visual Basic中的Using语句中的所有连接来执行此操作。未显式关闭的连接可能不会添加或返回到池中。有关更多信息,请参阅使用语句(C#参考)或如何:为Visual Basic处理系统资源(Visual Basic)。

所以,我建议您创建一个接口 IDbProvider 然后进行2次实现: SqlServerProvider SQLiteProvider 并处理内部的打开和关闭连接他们。然后使用Unity绑定一个或另一个提供者。

答案 1 :(得分:0)

在以单位形式实例化连接时,请勿打开它。但是,像往常一样在代码中首次使用时打开它,并在不再需要时关闭它。

这会改变您的DatabaseProvider

public class DatabaseProvider {
    private readonly IDbConnection _cn;

    public DatabaseProvider(IDbConnection cn) {
        _cn = cn;
    }

    public void ExecuteNonQuery(string query) {
        // Execute the query
        try{
           _cn.Open();
           var cmd = _cn.CreateCommand();
           cmd.CommandText = query;
           cmd.ExecuteNonQuery();
        }
        catch(ExpectedExceptions){
           //take care of business
        }
        finally{
            _cn.Close();
        }

    }
}

请注意Unity用于创建实例和跨越生命周期的范围。 上面的解决方案不是线程安全的,在不同的线程上使用相同的实例可以带来一个很好的调试功能。

答案 2 :(得分:0)

您也可以查看此内容。

以我的方式总是检查连接状态以及何时打开它。

public class DatabaseProvider {
    private readonly IDbConnection _cn;

    public DatabaseProvider(IDbConnection cn) {
        _cn = cn;
    }

    public void ExecuteNonQuery(string query) {

        using(SqliteCommand cmd = new SqliteCommand{ Connection = _cn})
        {

            if(_cn.State == ConnectionState.Open)
               _cn.Close();

            try
            {
               _cn.Open();
            }
            catch
            {
               // Message Connection Error
            }

            try
            {
               cmd.CommandText = query;
               cmd.ExecuteNonQuery();
            }
            catch
            {
                // Message Query Error
            }
            finally
            {
                _cn.Close();  // Connection close
            }

        }


    }
}