C# 保持数据库连接打开?
我的web应用程序具有以下类:C# 保持数据库连接打开?,c#,sql-server,sqlite,unit-testing,unity-container,C#,Sql Server,Sqlite,Unit Testing,Unity Container,我的web应用程序具有以下类: public class DatabaseProvider { private readonly IDbConnection _cn; public DatabaseProvider(IDbConnection cn) { _cn = cn; } public void ExecuteNonQuery(string query) { // Execute the query var
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();
}
}
其中,IDbConnection依赖项是使用以下代码(使用Microsoft Unity)声明的:
container.RegisterType(新注入工厂(c=>{
var cn=新的SqlConnection(“…”);
cn.Open();
返回cn;
}));
这允许我交换到SQLite的连接,如下所示:
container.RegisterType<IDbConnection>(new InjectionFactory(c => {
var cn = new SQLiteConnection("Data Source=:memory:;Version=3;");
cn.Open();
return cn;
}));
container.RegisterType(新注入工厂(c=>{
var cn=new-SQLiteConnection(“数据源=:内存:;版本=3;”;
cn.Open();
返回cn;
}));
我在测试时使用SQLite,连接必须保持打开状态,否则数据会丢失。因此,我不能在需要时打开和关闭连接
我总是在需要时打开与数据库的连接,我想知道这是否可以扩展到大型应用程序
如果您能就如何改进这一点提出建议,我将不胜感激。谢谢,作为ADO.NET中的一般规则,必须尽快关闭连接 连接从连接池中重复使用,是稀缺资源 推荐的方法是使用(){}构造 我们强烈建议您在使用完毕后始终关闭连接,以便连接将返回到池中。您可以使用Connection对象的Close或Dispose方法,或者通过打开C#中的using语句或Visual Basic中的using语句中的所有连接来完成此操作。未显式关闭的连接可能不会添加或返回到池中。有关详细信息,请参见使用语句(C#引用)或如何:为Visual Basic处置系统资源(Visual Basic)
因此,我建议您创建一个接口IDbProvider,然后创建两个实现:SqlServerProvider和SQLiteProvider,并处理它们内部的打开和关闭连接。然后使用Unity绑定一个或另一个提供程序。在Unity中实例化连接时不要打开它。但是,像往常一样,在第一次在代码中使用时打开它,在不再需要时关闭它 这将更改数据库提供程序
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用于创建实例的范围和跨越的生存期。
上面的解决方案不是线程安全的,在不同的线程上有相同的实例可以带来一个很好的调试fest。您也可以检查这个 以我的方式,总是检查连接状态,当它打开时关闭它
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
}
}
}
}
谢谢你的回答。我把Petar的答案打上了记号,因为它提供了更多的细节。谢谢,这大概就是我的想法。@Petar Repac,你能告诉我为什么你说连接是稀缺资源吗?这是什么意思?谢谢。@dan,创建到DB的新连接的成本很高(需要与DB协商各种细节),正因为如此,.NET保留了一个已创建连接的“池”,以便您的代码可以重用池中的一个连接,而不是总是创建一个新的连接。但是您的代码必须表现良好,并且在使用DB之后,必须将连接返回到池中。@Petar Repac,感谢您的澄清。所以,当你说连接创建是昂贵的,这不意味着离开开放的连接是非常明智的吗?我之前关于“连接是恐惧资源”的问题就是关于这一点的。再次感谢并非常感谢您对此的想法。
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
}
}
}
}