#vb.net #datatable #datagrid #sqlcommand #dataadapter
#vb.net #datatable #datagrid #sqlcommand #dataadapter
Вопрос:
Я написал общий VB.net подпрограмма, которая заполняет сетку данных результатами запроса. Подпрограмма в качестве одного параметра, strQuery, которая представляет собой строку, которая может преобразовываться в любое допустимое представление SQL-сервера или хранимую процедуру, которая возвращает набор записей. Кроме этого, нет никаких ограничений на код SQL, и отправка двух запросов с совершенно разными профилями полей является допустимым предложением.
Чтобы заставить это работать, я должен полностью очистить сетку данных от любого набора данных, который был там ранее, что позволит элементу управления отказаться от своего предыдущего идентификатора и начать все сначала, позволяя с нуля новому набору данных переопределить содержимое элемента управления.
Я, наконец, решил проблему. Возможно, мне следовало упомянуть, что я использую Visual Studio 2010, и что если Херси использовал более позднюю версию, то код, который работал для него, возможно, не работал для меня. Изменение в моем коде — это одна дополнительная строка: присвоение имени и datapropertyname одного и того же имени. Я заметил, что, когда я перешел к просмотру представления столбца, я заметил, что datapropertyname — это то, как таблица ссылается на источник, а имя является эффективным псевдонимом для поля, как оно будет представлено. Очевидно, что для ясности оба должны быть одинаковыми! Теперь это работает так, как рекламируется. Спасибо, ~ Питер Фербер
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
Dim con As New SqlConnection("<Enter Connection string here>")
Dim rcd As ADODB.Recordset = ReturnRecordset("Select * From ExcludeWords")
Call DefineDataGrid("Select * From ExcludeWords")
End Sub
Private Sub btnUpdate_Click(sender As System.Object, e As System.EventArgs) Handles btnUpdate.Click
Call DefineDataGrid("Select * From FindWords")
End Sub
Sub DefineDataGrid(ByVal strQuery As String)
Dim con As New SqlConnection("<Enter Connection String Here>")
Dim dt As New DataTable
FindWordGrid.Columns.Clear()
FindWordGrid.DataSource = Nothing
Dim rcd As ADODB.Recordset = ReturnRecordset(strQuery)
Dim MyField As ADODB.Field
Dim iCount As Integer = -1
FindWordGrid.ColumnCount = rcd.Fields.Count
For Each MyField In rcd.Fields
iCount = iCount 1
FindWordGrid.Columns(iCount).Name = MyField.Name
FindWordGrid.Columns(iCount).DataPropertyName = MyField.Name
Next
Dim cmd As New SqlCommand(strQuery, con)
Dim da = New SqlDataAdapter(cmd)
da.Fill(dt)
FindWordGrid.DataSource = dt
End Sub
Function ReturnRecordset(strQuery As String) As ADODB.Recordset
Dim con As ADODB.Connection = "<Enter Connection string here>"
ReturnRecordset = New ADODB.Recordset
ReturnRecordset.Open(strQuery, con)
End Function
Мою настройку легко воспроизвести: я использую наборы данных, содержащие всего несколько записей в каждой соответствующей таблице. Единственным ограничением является то, что соответствующие прогоны должны иметь другой профиль поля. Я экспериментировал с различными методами большую часть дня, и теперь я думаю, что лучше всего получить немного нового серого материала по этому вопросу. Правильное выполнение этого процесса — последнее серьезное препятствие для меня в создании ключевой презентации, которую я хочу сделать, в лоббировании должности. Заранее спасибо за ваши комментарии, мысли и идеи.
С уважением, ~ Питер Фербер
Комментарии:
1. Во-первых, ваш код не будет работать с «любым допустимым представлением SQL-сервера или хранимой процедурой». Это будет работать только с фактическим
SELECT
оператором, потому что вы принимаете значение по умолчаниюCommandType
Text
.2. Если после привязки нет строк, то в источнике данных нет строк. Вы можете проверить, сколько записей было извлечено, посмотрев на число, возвращенное
Fill
методом.3. Спасибо всем за ваши ответы. В попытке очистить коллекцию столбцов я добавил следующую строку:
4. Если ваши запросы могут не выдавать результирующие наборы с той же схемой, вам необходимо очистить существующие столбцы из сетки. Для этого установите значение
DataSource
toNothing
,Clear
Columns
collection, а затем установитеDataSource
снова. Это автоматически сгенерирует новые столбцы.5. Спасибо всем за ваши ответы. В попытке очистить коллекцию столбцов я изменил блок кода в исходном вопросе, чтобы показать мою обновленную попытку следовать инструкциям jmcihinney. Когда я это делаю, либо выше, либо ниже строки, устанавливающей источник данных в nothing, я получаю пустую сетку данных при первом проходе. При написании «FindWordGrid. Столбцы. Clear ()», что-то, похоже, полностью демонтирует функциональность сетки данных. Я делаю что-то не так? С уважением, могу ли я предложить воспроизвести простую настройку, которую я описал, и протестировать ваши исправления? Спасибо. ~ Peter Ferber
Ответ №1:
Итак, внес пару изменений в опубликованный вами код DefineDataGrid. Кажется, это работает для меня. Я подозреваю, что это может быть как-то связано с жизненным циклом ваших объектов cmd или con, вызывающих вашу проблему. Разбор нескольких разных запросов к нему, и он правильно перестраивает datagridview
Sub DefineDataGrid(ByVal strQuery As String)
Dim dt As New DataTable
FindWordGrid.DataSource = Nothing
Using con As New SqlConnection("Your Connection String Here")
Using cmd As New SqlCommand(strQuery, con)
Dim da = New SqlDataAdapter(cmd)
da.Fill(dt)
FindWordGrid.DataSource = dt
End Using
End Using
End Sub
Изменил очевидные реализации con и cmd на уровне модуля на локальные переменные, и поскольку оба типа реализуют IDisposable, обернул их в шаблон Using
Комментарии:
1. Это потрясающе, Херси. Спасибо за должную осмотрительность в этом вопросе. Я получаю сообщение об ошибке во второй раз, когда сталкиваюсь со строкой «da.Fill (dt)», и я получаю сообщение об ошибке «Свойство connectionstring не инициализировано». Это нормально, и мне кажется, что ваша оценка жизненного цикла — правильный путь. Я буду продолжать нудеть. То, что вы добились успеха с вашей стороны, говорит мне о том, что решение уже близко. Большое спасибо!
2. @user3621522, в опубликованном коде явно указано «Ваша строка подключения здесь» , поэтому, если ваше
ConnectionString
свойство не задано, вы проигнорировали эту часть.3. Опубликованный код пренебрегает очисткой столбцов сетки после очистки
DataSource
, что означает, что столбцы из предыдущих запросов останутся.4. Это потрясающе, Херси. Спасибо за должную осмотрительность в этом вопросе. Я получал сообщение об ошибке во второй раз, когда сталкивался со строкой «da.Fill (dt)», в которой говорилось: «Свойство connectionstring не инициализировано». Итак, я изменил созданное новое соединение внутри подпрограммы, и это предотвращает возникновение ошибки, но старая конфигурация поля все еще действует во время второго запуска. Я уверен, что я на правильном пути, так как у вас есть проверенный показатель успеха при использовании этого метода. Хорошая работа, и спасибо!
5. @user3621522, может быть, обновите свой вопрос своей последней попыткой и укажите, как вы создаете свое соединение