Tworzenie prostej aplikacji danych przy użyciu ADO.NET
Notatka
Zestawy danych i powiązane klasy to starsze technologie .NET Framework z początku 2000 roku, które umożliwiają aplikacjom pracę z danymi w pamięci, gdy aplikacje są odłączone od bazy danych. Technologie te są szczególnie przydatne w przypadku aplikacji, które umożliwiają użytkownikom modyfikowanie danych i utrwalanie zmian z powrotem w bazie danych. Mimo że zestawy danych okazały się bardzo udaną technologią, zalecamy, aby nowe aplikacje platformy .NET używały Entity Framework Core. Program Entity Framework zapewnia bardziej naturalny sposób pracy z danymi tabelarycznymi jako modelami obiektów i ma prostszy interfejs programowania.
Podczas tworzenia aplikacji, która manipuluje danymi w bazie danych, wykonujesz podstawowe zadania, takie jak definiowanie parametrów połączenia, wstawianie danych i uruchamianie procedur składowanych. Korzystając z tego tematu, możesz dowiedzieć się, jak wchodzić w interakcję z bazą danych w ramach prostej aplikacji Windows Forms, stosując schemat "formularze nad danymi" przy użyciu języków Visual C# lub Visual Basic oraz ADO.NET. Wszystkie technologie danych platformy .NET — w tym zestawy danych, LINQ to SQL i Entity Framework — ostatecznie wykonują kroki bardzo podobne do tych przedstawionych w tym artykule.
W tym artykule przedstawiono prosty sposób szybkiego pobierania danych z bazy danych. Jeśli aplikacja musi modyfikować dane w sposób nietrywialny i aktualizować bazę danych, należy rozważyć użycie programu Entity Framework i użycie powiązania danych w celu automatycznego synchronizowania kontrolek interfejsu użytkownika ze zmianami w danych bazowych.
Ważny
Aby kod był prosty, nie zawiera obsługi wyjątków na poziomie produkcji.
Notatka
Pełny kod tego samouczka można uzyskać w repozytorium GitHub dokumentacji programu Visual Studio w C# i Visual Basic.
Warunki wstępne
Aby utworzyć aplikację, potrzebne są następujące elementy:
Program Visual Studio z zainstalowanymi tworzeniem aplikacji klasycznych platformy .NET oraz magazynem danych i przetwarzaniem obciążeń. Aby je zainstalować, otwórz Instalator programu Visual Studio i wybierz Modyfikuj (lub Więcej>Modyfikuj) obok wersji programu Visual Studio, którą chcesz zmodyfikować.
SQL Server Express LocalDB. Jeśli nie masz bazy danych SQL Server Express LocalDB, możesz zainstalować ją ze strony pobierania programu SQL Server.
W tym temacie założono, że znasz podstawowe funkcje środowiska IDE programu Visual Studio i możesz tworzyć aplikację Windows Forms, dodawać formularze do projektu, umieszczać przyciski i inne kontrolki na formularzach, ustawiać właściwości kontrolek i kodować proste zdarzenia. Jeśli nie znasz tych zadań, zalecamy ukończenie Tworzenie aplikacji Windows Forms w programie Visual Studio przy użyciu programu Visual Basic samouczka lub samouczka Tworzenie aplikacji Windows Forms w programie Visual Studio przy użyciu języka C# samouczka przed rozpoczęciem tego przewodnika.
Konfigurowanie przykładowej bazy danych
Utwórz przykładową bazę danych, wykonując następujące kroki:
W programie Visual Studio otwórz okno Eksploratora serwera.
Kliknij prawym przyciskiem myszy pozycję Połączenia danych i wybierz pozycję Utwórz nową bazę danych programu SQL Server.
W polu tekstowym nazwa serwera wpisz (localdb)\mssqllocaldb.
W polu tekstowym Nowa nazwa bazy danych wprowadź Sales, a następnie wybierz pozycję OK.
Pusta baza danych Sales jest tworzona i dodawana do węzła Połączenia danych w Eksploratorze serwera.
Kliknij prawym przyciskiem myszy połączenie danych Sales i wybierz pozycję Nowe zapytanie.
Zostanie otwarte okno edytora zapytań.
Skopiuj skrypt Sales Transact-SQL do schowka.
Wklej skrypt języka T-SQL do edytora zapytań, a następnie wybierz przycisk Wykonaj.
Po krótkim czasie zapytanie zakończy działanie i zostaną utworzone obiekty bazy danych. Baza danych zawiera dwie tabele: Customer (Klient) i Orders (Zamówienia). Te tabele nie zawierają początkowo żadnych danych, ale można dodawać dane podczas uruchamiania tworzonej aplikacji. Baza danych zawiera również cztery proste procedury składowane.
Tworzenie formularzy i dodawanie kontrolek
Utwórz projekt w języku C# lub Visual Basic przy użyciu szablonu Windows Forms App (.NET Framework), a następnie nadaj mu nazwę SimpleDataApp.
Program Visual Studio tworzy projekt i kilka plików, w tym pusty formularz systemu Windows o nazwie Form1.
Dodaj do projektu dwa formularze systemu Windows, aby miał trzy formularze, a następnie nadaj im następujące nazwy:
Nawigacja
NowyKlient
WypełnijLubAnuluj
Dla każdego formularza dodaj pola tekstowe, przyciski i inne kontrolki, które są wyświetlane na poniższych ilustracjach. Dla każdej kontrolki ustaw właściwości opisane w tabelach.
Nota
Pole grupy i kontrolki etykiety dodają jasność, ale nie są używane w kodzie.
formularz nawigacji
okno dialogowe nawigacji
Kontrolki formularza nawigacji | Właściwości |
---|---|
Przycisk | Nazwa = btnGoToAdd |
Przycisk | Name = btnGoToFillOrCancel |
Przycisk | Nazwa = btnExit |
formularz NowyKlient
Kontrolki formularza NewCustomer | Właściwości |
---|---|
Pole tekstowe | Nazwa = txtCustomerName |
Pole tekstowe | Nazwa = txtCustomerID Tylko do odczytu = True |
Przycisk | Name = btnUtwórzKonto |
Przycisk numeryczny góra-dół | Liczba miejsc dziesiętnych: 0 Maksimum = 5000 Nazwa = numOrderAmount |
DateTimePicker | Format = krótki Name = dtpOrderDate |
Przycisk | Name = btnPlaceOrder |
Przycisk | Nazwa = btnAddAnotherAccount |
Przycisk | Nazwa = btnAddFinish |
formularz FillOrCancel
Kontrolki formularza FillOrCancel | Właściwości |
---|---|
Pole tekstowe | Nazwa = txtOrderID |
Przycisk | Name = btnFindByOrderID |
DateTimePicker | Format = krótki Name = dtpFillDate |
DataGridView | Nazwa = dgvCustomerOrders Tylko do odczytu = True RowHeadersVisible = Fałsz |
Przycisk | Name = btnAnulujZamówienie |
Przycisk | Name = btnFillOrder |
Przycisk | Name = btnFinishUpdates |
Przechowaj ciąg połączenia
Gdy aplikacja próbuje otworzyć połączenie z bazą danych, aplikacja musi mieć dostęp do parametrów połączenia. Aby uniknąć ręcznego wprowadzania ciągu w każdym formularzu, zapisz ciąg w pliku App.config w projekcie i utwórz metodę zwracającą ciąg, gdy metoda jest wywoływana z dowolnego formularza w aplikacji.
Parametry połączenia można znaleźć, klikając prawym przyciskiem myszy połączenie danych Sales w Server Explorer i wybierając pozycję Właściwości. Znajdź właściwość ConnectionString, a następnie użyj Ctrl+A, Ctrl+C, aby zaznaczyć i skopiować ciąg do schowka.
Jeśli używasz języka C#, w Eksploratorze rozwiązańrozwiń węzeł Właściwości w projekcie, a następnie otwórz plik Settings.settings. Jeśli używasz programu Visual Basic, w Eksploratorze rozwiązań , kliknij pozycję Pokaż wszystkie pliki, rozwiń węzeł My Project, a następnie otwórz plik Settings.settings.
W kolumnie Nazwa wprowadź
connString
.Na liście Typ wybierz (ciąg połączenia).
Na liście Zakres wybierz Application.
W kolumnie Wartość wprowadź parametry połączenia (bez cudzysłowów zewnętrznych), a następnie zapisz zmiany.
Ostrożność
W rzeczywistej aplikacji należy bezpiecznie przechowywać parametry połączenia zgodnie z opisem w Parametry połączenia i pliki konfiguracji. Aby uzyskać najlepsze zabezpieczenia, należy użyć metody uwierzytelniania, która nie polega na przechowywaniu hasła w parametrach połączenia, takich jak uwierzytelnianie systemu Windows dla lokalnej bazy danych programu SQL Server. Zobacz Zapisywanie i edytowanie parametrów połączenia.
Pisanie kodu formularzy
Ta sekcja zawiera krótkie omówienie tego, co robi każdy formularz. Udostępnia również kod, który definiuje podstawową logikę po kliknięciu przycisku na formularzu.
Formularz nawigacji
Po uruchomieniu aplikacji zostanie otwarty formularz nawigacji. Przycisk Dodaj konto otwiera formularz NewCustomer. Przycisk Wypełnij lub anuluj zamówienia otwiera formularz FillOrCancel. Przycisk Wyjście zamyka aplikację.
Ustaw formularz nawigacyjny jako formularz startowy
Jeśli używasz języka C#, w eksploratorze rozwiązań otwórz Program.cs, a następnie zmień wiersz Application.Run
na następujący: Application.Run(new Navigation());
Jeśli używasz programu Visual Basic, w Eksploratorze rozwiązańotwórz okno Właściwości, wybierz kartę Aplikacja, a następnie wybierz SimpleDataApp.Navigation na liście Formularz uruchamiania.
Tworzenie automatycznie wygenerowanych programów obsługi zdarzeń
Kliknij dwukrotnie trzy przyciski w formularzu nawigacji, aby utworzyć puste metody obsługi zdarzeń. Dwukrotne kliknięcie przycisków powoduje również dodanie automatycznie wygenerowanego kodu w pliku kodu projektanta, który umożliwia kliknięcie przycisku w celu wywołania zdarzenia.
Notatka
Jeśli pominiesz akcję dwukrotnego kliknięcia w projektancie i po prostu skopiuj kod i wklej go do plików kodu, nie zapomnij ustawić procedury obsługi zdarzeń na właściwą metodę. Można to zrobić w oknie właściwości . Przejdź do karty Zdarzenia (użyj przycisku z ikoną pioruna na pasku narzędzi) i wyszukaj program obsługi zdarzeń Kliknij.
Dodawanie kodu dla logiki formularza nawigacji
Na stronie kodowej formularza nawigacji wypełnij elementy metody dla trzech procedur obsługi zdarzeń kliknięcia przycisku, jak pokazano w poniższym kodzie.
/// <summary>
/// Opens the NewCustomer form as a dialog box,
/// which returns focus to the calling form when it is closed.
/// </summary>
private void btnGoToAdd_Click(object sender, EventArgs e)
{
Form frm = new NewCustomer();
frm.Show();
}
/// <summary>
/// Opens the FillorCancel form as a dialog box.
/// </summary>
private void btnGoToFillOrCancel_Click(object sender, EventArgs e)
{
Form frm = new FillOrCancel();
frm.ShowDialog();
}
/// <summary>
/// Closes the application (not just the Navigation form).
/// </summary>
private void btnExit_Click(object sender, EventArgs e)
{
this.Close();
}
Notatka
Kod tego samouczka jest dostępny w językach C# i Visual Basic. Aby przełączyć język kodu na tej stronie między językami C# i Visual Basic, użyj przełącznika języka kodu w górnej części każdego przykładu kodu.
Formularz NowyKlient
Po wprowadzeniu nazwy klienta, a następnie wybraniu przycisku Utwórz konto formularz NewCustomer tworzy konto klienta, a program SQL Server zwraca wartość IDENTITY jako nowy identyfikator klienta. Następnie możesz złożyć zamówienie dla nowego konta, określając kwotę i datę zamówienia oraz wybierając przycisk Złóż zamówienie.
Tworzenie automatycznie wygenerowanych programów obsługi zdarzeń
Utwórz pustą procedurę obsługi zdarzeń Click dla każdego przycisku w formularzu NewCustomer, klikając dwukrotnie każdy z czterech przycisków. Dwukrotne kliknięcie przycisków powoduje również dodanie automatycznie wygenerowanego kodu w pliku kodu projektanta, który umożliwia kliknięcie przycisku w celu wywołania zdarzenia.
Dodawanie kodu dla logiki formularza NewCustomer
Aby ukończyć logikę formularza NewCustomer, wykonaj następujące kroki.
Wprowadź przestrzeń nazw
System.Data.SqlClient
do zakresu, aby nie trzeba było w pełni kwalifikować nazw jej członków.Dodaj kilka zmiennych i metod pomocnika do klasy, jak pokazano w poniższym kodzie.
// Storage for IDENTITY values returned from database. private int parsedCustomerID; private int orderID; /// <summary> /// Verifies that the customer name text box is not empty. /// </summary> private bool IsCustomerNameValid() { if (txtCustomerName.Text == "") { MessageBox.Show("Please enter a name."); return false; } else { return true; } } /// <summary> /// Verifies that a customer ID and order amount have been provided. /// </summary> private bool IsOrderDataValid() { // Verify that CustomerID is present. if (txtCustomerID.Text == "") { MessageBox.Show("Please create customer account before placing order."); return false; } // Verify that Amount isn't 0. else if ((numOrderAmount.Value < 1)) { MessageBox.Show("Please specify an order amount."); return false; } else { // Order can be submitted. return true; } } /// <summary> /// Clears the form data. /// </summary> private void ClearForm() { txtCustomerName.Clear(); txtCustomerID.Clear(); dtpOrderDate.Value = DateTime.Now; numOrderAmount.Value = 0; this.parsedCustomerID = 0; }
Ukończ elementy metody dla czterech procedur obsługi zdarzeń kliknięcia przycisku, jak pokazano w poniższym kodzie.
/// <summary> /// Creates a new customer by calling the Sales.uspNewCustomer stored procedure. /// </summary> private void btnCreateAccount_Click(object sender, EventArgs e) { if (IsCustomerNameValid()) { // Create the connection. using (SqlConnection connection = new SqlConnection(Properties.Settings.Default.connString)) { // Create a SqlCommand, and identify it as a stored procedure. using (SqlCommand sqlCommand = new SqlCommand("Sales.uspNewCustomer", connection)) { sqlCommand.CommandType = CommandType.StoredProcedure; // Add input parameter for the stored procedure and specify what to use as its value. sqlCommand.Parameters.Add(new SqlParameter("@CustomerName", SqlDbType.NVarChar, 40)); sqlCommand.Parameters["@CustomerName"].Value = txtCustomerName.Text; // Add the output parameter. sqlCommand.Parameters.Add(new SqlParameter("@CustomerID", SqlDbType.Int)); sqlCommand.Parameters["@CustomerID"].Direction = ParameterDirection.Output; try { connection.Open(); // Run the stored procedure. sqlCommand.ExecuteNonQuery(); // Customer ID is an IDENTITY value from the database. this.parsedCustomerID = (int)sqlCommand.Parameters["@CustomerID"].Value; // Put the Customer ID value into the read-only text box. this.txtCustomerID.Text = Convert.ToString(parsedCustomerID); } catch { MessageBox.Show("Customer ID was not returned. Account could not be created."); } finally { connection.Close(); } } } } } /// <summary> /// Calls the Sales.uspPlaceNewOrder stored procedure to place an order. /// </summary> private void btnPlaceOrder_Click(object sender, EventArgs e) { // Ensure the required input is present. if (IsOrderDataValid()) { // Create the connection. using (SqlConnection connection = new SqlConnection(Properties.Settings.Default.connString)) { // Create SqlCommand and identify it as a stored procedure. using (SqlCommand sqlCommand = new SqlCommand("Sales.uspPlaceNewOrder", connection)) { sqlCommand.CommandType = CommandType.StoredProcedure; // Add the @CustomerID input parameter, which was obtained from uspNewCustomer. sqlCommand.Parameters.Add(new SqlParameter("@CustomerID", SqlDbType.Int)); sqlCommand.Parameters["@CustomerID"].Value = this.parsedCustomerID; // Add the @OrderDate input parameter. sqlCommand.Parameters.Add(new SqlParameter("@OrderDate", SqlDbType.DateTime, 8)); sqlCommand.Parameters["@OrderDate"].Value = dtpOrderDate.Value; // Add the @Amount order amount input parameter. sqlCommand.Parameters.Add(new SqlParameter("@Amount", SqlDbType.Int)); sqlCommand.Parameters["@Amount"].Value = numOrderAmount.Value; // Add the @Status order status input parameter. // For a new order, the status is always O (open). sqlCommand.Parameters.Add(new SqlParameter("@Status", SqlDbType.Char, 1)); sqlCommand.Parameters["@Status"].Value = "O"; // Add the return value for the stored procedure, which is the order ID. sqlCommand.Parameters.Add(new SqlParameter("@RC", SqlDbType.Int)); sqlCommand.Parameters["@RC"].Direction = ParameterDirection.ReturnValue; try { //Open connection. connection.Open(); // Run the stored procedure. sqlCommand.ExecuteNonQuery(); // Display the order number. this.orderID = (int)sqlCommand.Parameters["@RC"].Value; MessageBox.Show("Order number " + this.orderID + " has been submitted."); } catch { MessageBox.Show("Order could not be placed."); } finally { connection.Close(); } } } } } /// <summary> /// Clears the form data so another new account can be created. /// </summary> private void btnAddAnotherAccount_Click(object sender, EventArgs e) { this.ClearForm(); } /// <summary> /// Closes the form/dialog box. /// </summary> private void btnAddFinish_Click(object sender, EventArgs e) { this.Close(); }
Formularz WypełnijLubAnuluj
Formularz FillOrCancel uruchamia zapytanie, aby zwrócić zamówienie po wprowadzeniu identyfikatora zamówienia, a następnie wybierz przycisk Znajdź zamówienie. Zwrócony wiersz jest wyświetlany w tabeli danych tylko do odczytu. Możesz oznaczyć zamówienie jako anulowane (X), jeśli wybierzesz przycisk Anuluj zamówienie lub możesz oznaczyć zamówienie jako wypełnione (F), jeśli wybierzesz przycisk Wypełnienie zamówienia. Jeśli ponownie wybierzesz przycisk Znajdź zamówienie, zostanie wyświetlony zaktualizowany wiersz.
Tworzenie automatycznie wygenerowanych programów obsługi zdarzeń
Utwórz puste procedury obsługi zdarzeń Click dla czterech przycisków w formularzu FillOrCancel, klikając dwukrotnie każdy z przycisków. Dwukrotne kliknięcie przycisków powoduje również dodanie automatycznie wygenerowanego kodu w pliku kodu projektanta, który umożliwia kliknięcie przycisku w celu wywołania zdarzenia.
Dodawanie kodu dla logiki formularza FillOrCancel
Aby ukończyć logikę formularza FillOrCancel, wykonaj następujące kroki.
Wprowadź następujące dwie przestrzenie nazw do zakresu, aby nie trzeba było w pełni kwalifikować nazw ich elementów.
Dodaj zmienną i metodę pomocnika do klasy, jak pokazano w poniższym kodzie.
// Storage for the order ID value. private int parsedOrderID; /// <summary> /// Verifies that an order ID is present and contains valid characters. /// </summary> private bool IsOrderIDValid() { // Check for input in the Order ID text box. if (txtOrderID.Text == "") { MessageBox.Show("Please specify the Order ID."); return false; } // Check for characters other than integers. else if (Regex.IsMatch(txtOrderID.Text, @"^\D*$")) { // Show message and clear input. MessageBox.Show("Customer ID must contain only numbers."); txtOrderID.Clear(); return false; } else { // Convert the text in the text box to an integer to send to the database. parsedOrderID = Int32.Parse(txtOrderID.Text); return true; } }
Ukończ elementy metody dla czterech procedur obsługi zdarzeń kliknięcia przycisku, jak pokazano w poniższym kodzie.
/// <summary> /// Executes a t-SQL SELECT statement to obtain order data for a specified /// order ID, then displays it in the DataGridView on the form. /// </summary> private void btnFindByOrderID_Click(object sender, EventArgs e) { if (IsOrderIDValid()) { using (SqlConnection connection = new SqlConnection(Properties.Settings.Default.connString)) { // Define a t-SQL query string that has a parameter for orderID. const string sql = "SELECT * FROM Sales.Orders WHERE orderID = @orderID"; // Create a SqlCommand object. using (SqlCommand sqlCommand = new SqlCommand(sql, connection)) { // Define the @orderID parameter and set its value. sqlCommand.Parameters.Add(new SqlParameter("@orderID", SqlDbType.Int)); sqlCommand.Parameters["@orderID"].Value = parsedOrderID; try { connection.Open(); // Run the query by calling ExecuteReader(). using (SqlDataReader dataReader = sqlCommand.ExecuteReader()) { // Create a data table to hold the retrieved data. DataTable dataTable = new DataTable(); // Load the data from SqlDataReader into the data table. dataTable.Load(dataReader); // Display the data from the data table in the data grid view. this.dgvCustomerOrders.DataSource = dataTable; // Close the SqlDataReader. dataReader.Close(); } } catch { MessageBox.Show("The requested order could not be loaded into the form."); } finally { // Close the connection. connection.Close(); } } } } } /// <summary> /// Cancels an order by calling the Sales.uspCancelOrder /// stored procedure on the database. /// </summary> private void btnCancelOrder_Click(object sender, EventArgs e) { if (IsOrderIDValid()) { // Create the connection. using (SqlConnection connection = new SqlConnection(Properties.Settings.Default.connString)) { // Create the SqlCommand object and identify it as a stored procedure. using (SqlCommand sqlCommand = new SqlCommand("Sales.uspCancelOrder", connection)) { sqlCommand.CommandType = CommandType.StoredProcedure; // Add the order ID input parameter for the stored procedure. sqlCommand.Parameters.Add(new SqlParameter("@orderID", SqlDbType.Int)); sqlCommand.Parameters["@orderID"].Value = parsedOrderID; try { // Open the connection. connection.Open(); // Run the command to execute the stored procedure. sqlCommand.ExecuteNonQuery(); } catch { MessageBox.Show("The cancel operation was not completed."); } finally { // Close connection. connection.Close(); } } } } } /// <summary> /// Fills an order by calling the Sales.uspFillOrder stored /// procedure on the database. /// </summary> private void btnFillOrder_Click(object sender, EventArgs e) { if (IsOrderIDValid()) { // Create the connection. using (SqlConnection connection = new SqlConnection(Properties.Settings.Default.connString)) { // Create command and identify it as a stored procedure. using (SqlCommand sqlCommand = new SqlCommand("Sales.uspFillOrder", connection)) { sqlCommand.CommandType = CommandType.StoredProcedure; // Add the order ID input parameter for the stored procedure. sqlCommand.Parameters.Add(new SqlParameter("@orderID", SqlDbType.Int)); sqlCommand.Parameters["@orderID"].Value = parsedOrderID; // Add the filled date input parameter for the stored procedure. sqlCommand.Parameters.Add(new SqlParameter("@FilledDate", SqlDbType.DateTime, 8)); sqlCommand.Parameters["@FilledDate"].Value = dtpFillDate.Value; try { connection.Open(); // Execute the stored procedure. sqlCommand.ExecuteNonQuery(); } catch { MessageBox.Show("The fill operation was not completed."); } finally { // Close the connection. connection.Close(); } } } } } /// <summary> /// Closes the form. /// </summary> private void btnFinishUpdates_Click(object sender, EventArgs e) { this.Close(); }
Testowanie aplikacji
Uruchom aplikację i spróbuj utworzyć kilku klientów i zamówienia, aby sprawdzić, czy wszystko działa zgodnie z oczekiwaniami. Aby sprawdzić, czy baza danych została zaktualizowana wraz ze zmianami, otwórz węzeł Tabele w Eksploratorze serwera , kliknij prawym przyciskiem myszy węzły Klienci i Zamówienia , a następnie wybierz Pokaż dane tabeli .