|
|
|
| Делаю код по книге Д. Сеппы:
Imports System.Data
Imports System.Data.OleDb
Imports System.Data.SqlClient
Public Class Form2
Private Sub Form2_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim strConn, strSQL1 As String
strConn = "Data Source=.\SQLExpress;Initial Catalog=Northwind;Integrated Security=True;Asynchronous Processing=True;"
strSQL1 = "Select OrderID, CustomerID, OrderDate, ShippedDate, ShipCity" & _
" From Orders Where ShipCountry='Canada'"
Dim cn As New SqlConnection(strConn)
cn.Open()
Dim cmd As SqlCommand = cn.CreateCommand()
cmd.CommandText = strSQL1
Dim rdr As SqlDataReader = cmd.ExecuteReader()
End Sub
Вопрос конечно же смешной, но как эти данные привязать к элементу на форме, DataGridView например ? В Аксе надо было прописывать RowSource, а здесь как? Может есть несколько вариантов. Все советы приветствуются. | |
|
| |
|
|
|
| Я уже здесь выкладывал пример привязки данных к гриду. Для этого нужно использовать объект DataSet
Using cn As New SqlConnection(strConn) 'Строка подключения
cn.Open()
Dim cmd As SqlCommand
cmd = New SqlCommand(strSQL1, cn)
Dim da1 As New SqlDataAdapter(cmd)
Dim ds1 As New DataSet()
da1.Fill(ds1)
Me.DataGrid1.DataSource = ds1
Me.DataGrid1.DataBind()
cmd.Connection.Close()
cmd.Connection.Dispose()
End Using
|
| |
|
| |
|
|
|
| Лучше использовать для подключения коннектион стринг билдер.
Прописав его один раз в отдельном классе, потом можно вызыватьв формах
Вот пример заполнения комбобока с использованием SqlConnectionStringBuilder-а
Imports System.Data.SqlClient.SqlConnectionStringBuilder
.........
Dim conn As New SqlConnectionStringBuilder()
conn.DataSource = имя сервера
conn.InitialCatalog = имя базы
conn.IntegratedSecurity = True
Using cn As New SqlConnection(conn.ConnectionString)
cn.Open()
strSQL = " SELECT * FROM TblMyTable "
Dim da1 As New SqlDataAdapter(strSQL, cn)
Dim ds1 As New DataSet()
da1.Fill(ds1, "TblMyTable ")
With ds1
Me.ComboBox1.DataSource = .Tables("TblMyTable ")
Me.ComboBox1.DisplayMember = "Name"
Me.ComboBox1.ValueMember = "Id"
End With
End Using
|
| |
|
| |
|
|
|
| Покопался по форумам и заработало следующим образом:
Imports System.Data
Imports System.Data.OleDb
Imports System.Data.SqlClient
Public Class Form2
Private Sub Form2_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim strConn, strSQL1 As String
strConn = "Data Source=.\SQLExpress;Initial Catalog=Northwind;Integrated Security=True;Asynchronous Processing=True;"
strSQL1 = "Select OrderID, CustomerID, OrderDate, ShippedDate, ShipCity" & _
" From Orders Where ShipCountry='Canada'"
Dim cn As New SqlConnection(strConn)
cn.Open()
Dim cmd As SqlCommand
cmd = New SqlCommand(strSQL1, cn)
Dim da1 As New SqlDataAdapter(cmd)
Dim ds1 As New DataSet()
da1.Fill(ds1, "Orders")
DataGridView1.DataBindings.Add("", (ds1), "Orders")
DataGridView1.DataMember = "Orders"
DataGridView1.DataSource = ds1
cmd.Connection.Close()
cmd.Connection.Dispose()
End Sub
End Class
всё равно тяжело пока, всё надо обмыслить.
Тогда при чём здесь ExecuteReader?
Получается, что примеры неполные или не подходят для 3,5. | |
|
| |
|
|
|
| Тот кусок кода, который вы выложили в первый раз формирует объект DataReader и наполняет его данными из базы.
С этим объектом (DataReader) далее у вас ничего не происходит. Вы его не читаете и ничего не делаете с данными. По аналогии с аксом - сделали рекордсет, наполнили его, и на этом остановились.
Так, что пример вполне нормальный. И подходит под любую версию .NET | |
|
| |
|
|
|
| А в том примере, который вы нашли на форуме - у вас открывается соединение, и затем оно не закрывается. А это не есть гуд. В последствии убедитесь в этом.
Настоятельно рекомендую использовать конструкцию
Using соединение
EndUsing
В этом случае конструкция сама позаботится о разрыве соединения.
Дописано:
Тогда при чём здесь ExecuteReader?
|
Эта команда заполняет объект DataReader | |
|
| |
|
|
|
| спасибо за совет, постараюсь разобраться и придерживаться его. | |
|
| |
|
|
|
| и вот что в итоге получилось, рабочий пример:
Imports System.Data
Imports System.Data.OleDb
Imports System.Data.SqlClient
Public Class форма1
Private Sub форма1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim strConn, strSQL1 As String
strConn = "Data Source=.\SQLExpress;Initial Catalog=Northwind;Integrated Security=True;" 'Asynchronous Processing=True;"
Using cn As New SqlConnection(strConn) 'Строка подключения
cn.Open()
strSQL1 = "Select OrderID, CustomerID, OrderDate, ShippedDate, ShipCity" & _
" From Orders Where ShipCountry='Canada'"
Dim cmd1 As SqlCommand
cmd1 = New SqlCommand(strSQL1, cn)
Dim da1 As New SqlDataAdapter(cmd1)
Dim ds1 As New DataSet()
da1.Fill(ds1, "Orders")
DataGridView1.DataBindings.Add("", (ds1), "Orders")
DataGridView1.DataMember = "Orders"
Me.DataGridView1.DataSource = ds1
cmd1.Connection.Close()
cmd1.Connection.Dispose()
End Using
End Sub
End Class | |
|
| |
|
|
|
|
| Покопался в примере выше и привязал ComboBox, вот, получилось:
Imports System.Data
Imports System.Data.OleDb
Imports System.Data.SqlClient
Imports System.Data.SqlClient.SqlConnectionStringBuilder
Public Class Form3
Private Sub Form3_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim strConn3 As New SqlConnectionStringBuilder()
Dim strSQL3 As String
'strConn3 = "Data Source=.\SQLExpress;Initial Catalog=Northwind;Integrated Security=True;"
strConn3.DataSource = ".\SQLExpress"
strConn3.InitialCatalog = "Northwind"
strConn3.IntegratedSecurity = True
Using cn3 As New SqlConnection(strConn3.ConnectionString)
cn3.Open()
strSQL3 = "SELECT DISTINCT CustomerID FROM Orders"
Dim da3 As New SqlDataAdapter(strSQL3, cn3)
Dim ds3 As New DataSet()
da3.Fill(ds3, "Orders")
With ds3
Me.ComboBox1.DataSource = .Tables("Orders")
Me.ComboBox1.DisplayMember = "CustomerID"
End With
End Using
End Sub
End Class
теперь ещё вопрос: как лучше связать два combobox а? В VBA через "SELECT ... "& имяпервого_combobox & "", а здесь как лучше сделать? | |
|
| |
|
|
|
| Я это делаю через хранимки ( stored procedure ). В качестве параметров передаю значения комбобоксов.
ЗЫ
Такую конструкцию
"SELECT ... "& имяпервого_combobox & ""
| в коде формы вообще не желательно использовать. | |
|
| |
|
|
|
| те Вы прописываете прямо в SQLServer? А потом вызываете её выполнение их VS? | |
|
| |
|
|
|
|
те Вы прописываете прямо в SQLServer? А потом вызываете её выполнение их VS?
|
Да.
Вот пример как вообще нужно правильно делать:
Вот хранимая процедура
CREATE PROCEDURE _spObl
@IdCountry int
AS
SELECT DISTINCT IdObl, OblName FROM TblKlassCity WHERE IdCountry = @IdCountry
/* SET NOCOUNT ON */
RETURN
|
Далее создается пользовательский класс
(Сорри за код на C#, но лень переписывать на VB)
using System.Data.SqlClient;
public class TranspProvider
{
public TranspProvider()
{
}
public DataSet DSObl(int DDlist) //- Создается ф-ция, возвращающая объект ДатаСет. В качестве принимаемого параметра используется целое число - значение из первого комбобокса
{
ConnClass st = new ConnClass();
using (SqlConnection cn = new SqlConnection(st.strConn()))
{
SqlCommand cmd = new SqlCommand("_spObl", cn); - вызывается созданная выше хранимая процедура
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("@IdCountry", DDlist); - ей передается параметр - целое число, равное значению первого комбобокса
Далее создаем и заполняем Датасет
cn.Open();
SqlDataAdapter daObl = new SqlDataAdapter(cmd);
DataSet dsObl = new DataSet();
daObl.Fill(dsObl);
cmd.Connection.Close();
cmd.Connection.Dispose();
return dsObl; - возвращаем датасет
}
}
}
|
А затем в коде прописываем
......
TranspProvider [b]TransProvider = new TranspProvider(); [/b]- создаем экземпляр TransProvider нашего пользовательского класса
........
Combo2.DataSource = TransProvider.DSObl(Convert.ToInt32 Combo1.SelectedValue)); - вызываем ф-цию DSObl из нашего пользовательского класса. В качестве входного параметра передается значение первого комбобоксаПоскольку результатом выполнения ф-ции является датасет, то делаем его источником для нашего комбобокса.
Combo2.DataTextField = "OblName";
Combo2.DataValueField = "IdObl";
Combo2.DataBind();...............
|
| |
|
| |
|
|
|
| О, блин, тока сейчас заметил.
Добавьте строку
ComboBox1.ValueMember = "Числовой Код, по которому будут выбираться значения"
По логике у вас должно быть что-то вроде
Me.ComboBox1.DataSource = .Tables("Orders")
Me.ComboBox1.DisplayMember = "CustomerName" -название клиента
ComboBox1.ValueMember ="CustomerID" - ID клиента | |
|
| |
|
|
|
| Не получится, сначала так и было. Выдаёт ошибку насчёт ValueMember. Пришлось редактировать. | |
|
| |
|
|
|
| Естественно выдаст. Вы же в селекте выбираете только CustomerID. | |
|
| |
|
|
|
| Вот, все же не поленился переписать классы на VB
Imports System.Data.SqlClient.SqlConnectionStringBuilder
Imports System.Data.SqlClient
Imports System.Windows.Forms.Form
Imports System.Data
Imports System.Data.DataSet
Imports System.Data.DataColumn
Public Class Class1
Public Function DSObl(ByVal DDlist As Integer) As DataSet
Dim strConn3 As New SqlConnectionStringBuilder()
strConn3.DataSource = ".\SQLExpress"
strConn3.InitialCatalog = "Имя базы"
strConn3.IntegratedSecurity = True
Using cn3 As New SqlConnection(strConn3.ConnectionString)
Dim cmd As New SqlCommand("_spObl", cn3)
cmd.CommandType = CommandType.StoredProcedure
cmd.Parameters.AddWithValue("@IdCountry", DDlist)
cn3.Open()
Dim daObl As New SqlDataAdapter(cmd)
Dim ds As New DataSet()
daObl.Fill(ds, "Obl")
cmd.Connection.Close()
cmd.Connection.Dispose()
Return ds
End Using
End Function
End Class
|
И далее на форме
Imports System.Drawing
Imports System.Data.SqlClient.SqlConnectionStringBuilder
Imports System.Data.SqlClient
Imports System.Windows.Forms.Form
Imports System.Data
Imports System.Data.DataSet
Imports System.Data.DataColumn
Public Class Form1
Dim dsprov As New Class1
Private Sub ComboBox1_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles ComboBox1.SelectedIndexChanged
Dim myds As New DataSet()
myds = dsprov.DSObl(Me.ComboBox1.SelectedValue)
With myds
Me.ComboBox1.DataSource = .Tables("Obl")
Me.ComboBox1.DisplayMember = "OblName"
Me.ComboBox1.ValueMember = "IdObl"
End With
End Sub
........
End Class
|
Текс хранимки остается таким же | |
|
| |
|
|
|
| Большое спасибо. Сам бы я нескоро к этому пришёл. Из ваших сообщений я понял, что связывать элементы управления лучше через stored procedure. Буду ковырять. Ещё раз СПАСИБО!!! | |
|
| |
|
|
|
|
Из ваших сообщений я понял, что связывать элементы управления лучше через stored procedure
|
Не только связывать элементы. Желательно все запросы с параметрами реализовывать через хранимые процедуры. | |
|
| |
|
|
|
| а насколько в этом может помочь LINQ toSQL? | |
|
| |
|
|
|
| Насколько сможет помочь - не знаю. Только не понятно - нафига козе баян?
Освойте сначала ADO.NET - а затем уже лезьте в LINQ. Хотя, конечно, решать вам.
Но без знаний и понимания принципов ADO.NET - в LINQ делать нечего, как в прочем и в .NET | |
|
| |
|