В .Net вам нужно обернуть соединения с базой данных в блок Try / Catch / finally и всегда закрывать соединения в разделе, наконец.Для этого существует сокращение, называемое Using
блоком.Это означает, что поддерживать соединение в качестве члена класса (как вы, кажется, делаете) почти всегда неверно..Net оптимизирован таким образом, что для каждого запроса лучше создавать новое соединение и объект команды.
DataReaders немного особенный: если вы возвращаете устройство чтения данных из блока, соединение может быть закрыто до вашего DataReader.сделано с этимВ C # я обычно обхожу проблему с помощью итератора (yield return).Поскольку в VB.Net отсутствует поддержка этой конструкции, я мог бы вместо этого использовать Action(Of IDataRecord)
, например:
Public Sub MyOracleQuery(ByVal id As Integer, ByVal ProcessRecord As Action(Of IDataRecord))
Dim sql As String = "SELECT <columns> FROM MyTable WHERE ID= @Id"
Using cn As New OracleConnection("connection string"), _
cmd As New OracleCommand(sql, cn)
cmd.Parameters.Add("@Id", SqlDbTypes.Int).Value = id
cn.Open()
Using (rdr As IDataReader = cmd.ExecuteReader())
While rdr.Read()
ProcessRecord(rdr)
End While
End Using
End Using
End Sub
Теперь вы можете передавать анонимный метод в этот код при его вызове:
Dim id As Integer
If Integer.TryParse(IDTextBox.Text, id) Then
MyOracleQuery(id, _
Function(r)
''#... Do something with each "r" here
End Function _
)
Else
''# Complain to user about invalid ID
End If
Обратите внимание, что для этого требуется многопоточный анонимный метод Visual Studio 2010 / .Net 4.Для более старых платформ вы можете объявить метод.