Используя DBDataReader
с 2 запросов , только первый выполняется, потому что нет способа сообщить, из какой таблицы/запроса находится каждый прочитанный элемент. Ваш цикл «двойного чтения», по-видимому, предполагает, что они будут возвращены в одно и то же время (а не один запрос за другим - так же, как они отправляются в DBCOmmand); если он сделал работать таким образом, он не сработает, если в каждой таблице не будет одинакового количества строк.
Использование DataTables
дает вам возможность просто связать результат ваших комбо вместо копирования данных в них:
Dim SQL = "SELECT * FROM Sample; SELECT * FROM Simple"
Dim ds As New DataSet
Using dbcon As New MySqlConnection(MySQLConnStr),
cmd As New MySqlCommand(SQL, dbcon)
dbcon.Open()
Dim da As New MySqlDataAdapter(cmd)
da.Fill(ds)
End Using
' debug results
Console.WriteLine(ds.Tables.Count)
Console.WriteLine(ds.Tables(0).Rows.Count)
Console.WriteLine(ds.Tables(1).Rows.Count)
Если я смотрю на окно вывода, он будет печатать 2
(таблицы), 10000
(строки в T (0)) и 6
(строки в T (1)). Не все DBProviders обладают этой возможностью. Доступ, например, захлестнет строку SQL. Другие изменения в способе составления кода:
- Объекты DBConnections и DBCommand должны быть удалены. Они выделяют ресурсы, поэтому их нужно создавать, использовать и удалять для выпуска этих ресурсов.
- Блок
Using
делает это для нас: целевые объекты создаются в начале и закрытии и размещаются на End Using
.
- Код выше складывает или объединяет 2 таких блока.
Код заполняет DataSet
из запроса, в этом случае создается 2 таблицы. Вместо того, чтобы копировать данные из одного контейнера в другой (например, управления), вы можете использовать в качестве DataTable
DataSource
:
cboDevName.DataSource = ds.Tables(0)
cboDevName.DisplayMember = "DevName" ' column names
cboDevName.ValueMember = "Id"
cboDevType.DataSource = ds.Tables(1)
cboDevType.DisplayMember = "DevType"
cboDevType.ValueMember = "DevCode"
Результат будет все строки из каждой таблицы появляются в соответствующем контроле со списком. Как правило, с этим типом, вы хотели бы ID/PK и имя, которое имеет смысл для пользователя в запросе. Пользователь видит дружественное имя (DisplayMember
), которое может легко получить доступ к уникальному идентификатору для выбора (ValueMember
).
При использовании связанных элементов управления списком, а не с помощью SelectedIndex
и SelectedIndexChanged
события, вы будете использовать SelectedValue
и SelectedItem
для доступа к фактическим данным.
MSDN: Using Statement (Visual Basic)
Большое вам спасибо за четкое объяснение. Но могу ли я узнать больше о 'Использовании'? Означает ли это, что мне не нужно закрывать соединение, когда я использую 'Using'? – Student
'Использование' закрывает и удаляет его. Как правило, все, что имеет метод 'Dispose', должно быть заключено в блок' Using'. – Plutonix