2

我的 Web 应用程序具有以下类:

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,连接必须保持打开状态,否则数据会丢失。因此,我不能在需要时打开和关闭连接。

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

我将不胜感激有关如何改进这一点的任何建议。谢谢

4

3 回答 3

5

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

连接从连接池中重复使用,是稀缺资源。

推荐的方法是使用 () {} 构造。

SQL Server 连接池 (ADO.NET)

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

因此,我建议您创建一个接口IDbProvider,然后进行 2 个实现:SqlServerProviderSQLiteProvider,并在其中处理打开和关闭连接。然后使用 Unity 绑定一个或另一个提供者。

于 2012-10-10T12:51:28.583 回答
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 用于创建实例的范围和跨越的生命周期。上面的解决方案不是线程安全的,在不同的线程上拥有相同的实例可以带来很好的调试。

于 2012-10-10T13:00:59.090 回答
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
            }

        }


    }
}
于 2017-09-17T03:03:58.527 回答