2012-03-16 80 views
4

我创建了以下方法:如何在呼叫者与他们结束后关闭连接?

public System.Data.OleDb.OleDbDataReader GetReader(string sqlQuery) 
    { 

      System.Data.OleDb.OleDbConnection myConnection = new System.Data.OleDb.OleDbConnection(); 
      LoadConnectionStrings(); 
      myConnection.ConnectionString = ConnectionString; 
      myConnection.Open(); 
      System.Data.OleDb.OleDbCommand myCommand = new System.Data.OleDb.OleDbCommand(sqlQuery, myConnection); 
      System.Data.OleDb.OleDbDataReader myReader = null; 
      myReader = myCommand.ExecuteReader(); 

      return myReader; 

    } 

代码千行依赖于它,我想我是不是真的想,当我实现了它......

无论如何,

。如果我以这种方式检索阅读器,我无法关闭连接,并且如果在阅读器调用read()方法之前关闭连接,它将在阅读并说与数据库的连接需要时爆炸被打开。

问题是,我如何关闭以前代码体的连接?或者所有的连接一般也许..

从我读的here如果你没有专门调用'close()'它不会被关闭,如果你使用的是2003访问文件,在一个受到伤害的世界里,你离开你的世界

+0

为什么不在关闭之前关闭? – 2012-03-16 16:49:42

+1

@Dor因为它没有消耗任何数据在这一点上 – 2012-03-16 16:50:20

+0

不幸的是,你不能:/ – 2012-03-16 16:51:37

回答

12

在这种情况下,连接需要保持开放状态才能让读者工作 - 但是,ExecuteReader有一个重载,可以让你为读者指定一个标志来关闭连接读者被关闭:

myReader = myCommand.ExecuteReader(CommandBehavior.CloseConnection); 

这允许呼叫者使用:

using(var reader = GetReader(query)) { 
    //... 
} 

并且当调用者完成读写器时连接将被完全关闭。

+0

谁会想到2个单词会节省数千行代码^ _^ – 2012-03-16 16:58:20

+1

不过,如果你有一个方法返回一个' IDataReader'它需要包含一个try/catch,在'command.ExecuteReader'引发的情况下关闭连接。 – Joe 2012-03-16 18:33:53

1

不知道它是否完全解决了您的问题,但您可以使用IDBcommand.ExecuteReader(CommandBehavior)过载。

如果您通过CommandBehavior.CloseConnection,那么当您的阅读器关闭时,数据库连接将会关闭。

1

我同意Marc的看法,但是希望用您的方法指出缺陷。

该机制隐藏了来自调用者的连接,因此调用者不能将其用于针对数据库的其他操作。它还将范围与读者的生命周期联系在一起,因此如果要采取其他行动,那么在处置读者之前必须进行。

让调用者控制连接可能会更好,只需将连接传递给GetReader方法即可。

1

我用做这样的事情:

IDataReader GetReader(...) 
{ 
    IDbConnection connection = ...; 
    try 
    { 
     IDbCommand command = ...; 
     command.Connection = connection; 
     connection.Open(); 
     return command.ExecuteReader(CommandBehavior.CloseConnection); 
    } 
    catch 
    { 
     connection.Close(); 
     throw; 
    } 
} 

这不会关闭IDbCommand,但在我的经验,这是OK,只要连接被关闭。