Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Note
Классы DataSet и связанные классы являются устаревшими технологиями .NET Framework с начала 2000-х годов, которые позволяют приложениям работать с данными в памяти, пока приложения отключены от базы данных. Технологии особенно полезны для приложений, которые позволяют пользователям изменять данные и сохранять изменения обратно в базу данных. Хотя наборы данных являются проверенными успешными технологиями, рекомендуемый подход для новых приложений .NET заключается в использовании Entity Framework Core. Entity Framework предоставляет более естественный способ работы с табличными данными в виде объектных моделей и имеет более простой интерфейс программирования.
При создании приложения, которое управляет данными в базе данных, обычно выполняются такие задачи, как определение строк подключения, вставка данных и выполнение хранимых процедур. Следуя этой статье, вы узнаете, как взаимодействовать с базой данных из приложения Windows Forms с использованием форм над данными (FOD) с помощью Visual C# или Visual Basic и ADO.NET. Все технологии данных .NET, включая наборы данных, LINQ (Language-Integrated запрос) в SQL и Entity Framework, в конечном счете выполняют действия, аналогичные этим шагам, приведенным в этой статье.
В этой статье показано, как быстро получить данные из базы данных. Если приложению необходимо изменить данные нетривиальными способами и обновить базу данных, рассмотрите возможность использования Entity Framework и привязки данных. Это позволяет элементам управления пользовательским интерфейсом автоматически синхронизировать изменения в базовых данных.
Чтобы получить доступ к полному коду этого руководства, ознакомьтесь с репозиторием GitHub для C# и Visual Basic.
Important
Чтобы код оставался простым, он не включает обработку исключений, готовую для использования в производственной среде.
Prerequisites
Visual Studio с установленными рабочими нагрузками разработки классических приложений .NET и хранилища данных и обработки рабочих нагрузок. Чтобы установить их, откройте Visual Studio Installer и выберите "Изменить " рядом с версией Visual Studio, которую вы хотите изменить.
SQL Server Express LocalDB. Если у вас нет SQL Server Express LocalDB, его можно установить на странице загрузки SQL Server.
В этой статье предполагается, что вы знакомы с основными функциями интегрированной среды разработки Visual Studio. Кроме того, предполагается, что вы можете создать приложение Windows Forms, добавить формы в проект, добавить кнопки и другие элементы управления в формы, задать свойства элемента управления и код простых событий. Если вы не знакомы с этими задачами, выполните инструкции по созданию приложения Windows Forms в Visual Studio с помощью C# или учебника по созданиюприложения Windows Forms в Visual Studio с помощью Visual Basic , прежде чем начать это пошаговое руководство.
Настройте образец базы данных
Создайте образец базы данных, выполнив следующие действия.
В Visual Studio откройте окно обозревателя серверов.
Щелкните правой кнопкой мыши подключения к данным и выберите "Создать базу данных SQL Server".
Для имени сервера введите (localdb)\mssqllocaldb.
В поле "Создать базу данных" введите "Продажи" и нажмите кнопку "ОК".
Visual Studio создает пустую базу данных sales под узлом "Подключения к данным " в обозревателе серверов.
Щелкните правой кнопкой мыши подключение к данным о продажах и выберите "Создать запрос".
Откроется окно редактора запросов.
Вставьте скрипт T-SQL в окно редактора запросов и нажмите кнопку "Выполнить".
Через некоторое время запрос завершает выполнение и создаются объекты базы данных. База данных содержит две таблицы: Customer и Orders. Эти таблицы изначально не содержат данных, но при запуске создаваемого приложения можно добавить данные. База данных также содержит пять основных хранимых процедур.
Создание форм и добавление элементов управления
Создайте проект C# или Visual Basic с помощью шаблона приложения Windows Forms (.NET Framework) и назовите его SimpleDataApp.
Visual Studio создает проект и несколько файлов, включая пустую форму Windows с именем Form1.
В обозревателе решений добавьте в проект две формы Windows, чтобы она получила в общей сложности три формы, и присвойте им следующие имена:
Navigation
NewCustomer
FillOrCancel
Для каждой формы добавьте текстовые поля, кнопки и другие элементы управления, показанные на следующих рисунках. Для каждого элемента управления задайте свойства, описываемые таблицами.
Note
Поле группы и элементы управления метками добавляют ясность, но не используются в коде.
форма навигации
Элементы управления для формы навигации
Текст элемента управления Тип элемента управления Свойства элемента управления Добавить учетную запись Button Имя = btnGoToAdd Заполнение или отмена заказа Button Name = btnGoToFillOrCancel Exit Button Name = btnExit форма НовыйКлиент
Элементы управления для формы NewCustomer
Текст метки и элемента управления Тип элемента управления Свойства элемента управления Имя клиента TextBox Имя = txtCustomerName Идентификатор клиента TextBox Name = txtCustomerID
Только для чтения = ИстинаСоздание учетной записи Button Name = btnCreateAccount Сумма заказа NumericUpdown Имя = numOrderAmount
DecimalPlaces = 0
Максимум = 5000Дата заказа DateTimePicker Name = dtpOrderDate
Формат = КраткийРазместить заказ Button Name = btnPlaceOrder Finish Button Name = btnAddFinish Добавление другой учетной записи Button Name = btnAddAnotherAccount форма ЗаполнитьИлиОтменить
Элементы управления для формы FillOrCancel
Текст метки и элемента управления Тип элемента управления Свойства элемента управления Идентификатор заказа TextBox Name = txtOrderID Поиск заказа Button Name = btnFindByOrderID При заполнении заказа... DateTimePicker Name = dtpFillDate
Формат = Краткий(None) DataGridView Имя = dgvCustomerOrders
Только для чтения = Истина
ВидимостьЗаголовковСтрок = ЛожьОтмена заказа Button Name = btnCancelOrder Заполнение заказа Button Name = btnFillOrder Finish Button Name = btnFinishUpdates
Сохранение строки подключения
Когда приложение пытается открыть подключение к базе данных, приложение должно иметь доступ к строке подключения. Чтобы избежать необходимости ввести строку вручную в каждой форме, сохраните строку в файле App.config в проекте. Затем создайте метод, который возвращает строку при вызове метода из любой формы в приложении.
Чтобы найти строку подключения, выполните следующие действия.
В обозревателе серверов щелкните правой кнопкой мыши подключение к данным о продажах и выберите пункт "Свойства".
Найдите свойство Строки подключения и скопируйте его строковое значение в буфер обмена.
Чтобы сохранить строку подключения в проекте, выполните следующие действия.
В обозревателе решений выполните одно из следующих действий в зависимости от типа проекта:
Для проекта C# разверните узел свойств в проекте, а затем откройте файл Settings.settings .
Для проекта Visual Basic выберите "Показать все файлы", разверните узел "Мой проект ", а затем откройте файл Settings.settings .
В столбце "Имя" введите connString.
В списке "Тип " выберите (строка подключения).
В списке области выберите Приложение.
В столбце значений введите строку подключения (без внешних кавычек), а затем сохраните изменения.
Caution
В реальном приложении необходимо безопасно хранить строку подключения, как описано в разделе строки подключения и файлы конфигурации. Для обеспечения оптимальной безопасности используйте метод проверки подлинности, который не зависит от хранения пароля в строке подключения. Например, проверка подлинности Windows для локальной базы данных SQL Server. Дополнительные сведения см. в разделе "Сохранение и изменение строк подключения".
Написание кода для форм
В этом разделе содержатся краткие сведения о том, что делает каждая форма. Он также предоставляет код, определяющий базовую логику при выборе кнопки в форме.
Форма навигации
Форма навигации открывается при запуске приложения и включает следующие кнопки:
Добавление учетной записи: открывает форму NewCustomer .
Заполнение или отмена заказов: открывает форму FillOrCancel .
Выход: закрывает приложение.
Сделайте форму навигации формой запуска
Для проектов C#:
В обозревателе решенийоткройте Program.cs.
Измените строку на
Application.Run:Application.Run(new Navigation());
Для проектов Visual Basic:
В обозревателе решений щелкните проект правой кнопкой мыши и выберите "Свойства".
В конструкторе проектов выберите вкладку "Приложение " и выберите "Навигация " в списке объектов запуска .
Создание автоматически генерируемых обработчиков событий для формы навигации
Чтобы создать пустые методы обработчика событий, дважды щелкните каждую из трех кнопок в форме навигации. Дважды щелкнув кнопку, в файл кода конструктора добавляется автоматически созданный код, который позволяет выбрать кнопку для создания события.
Если вы решили скопировать и вставить код непосредственно в файлы кода, а не использовать действие двойного щелчка в конструкторе, убедитесь, что обработчик событий установлен на правильный метод:
В окне Свойства файла кода формы перейдите на вкладку События с помощью кнопки с изображением молнии на панели инструментов.
Найдите свойство Click и убедитесь, что его значение является правильным методом обработчика событий.
Добавление кода для логики формы навигации
На странице кода для формы навигации заполните тела методов для трех обработчиков событий выбора кнопки, как показано в следующем коде.
/// <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();
}
Форма нового клиента
При вводе имени клиента и нажатии кнопки "Создать учетную запись " форма NewCustomer создает учетную запись клиента, а SQL Server возвращает значение IDENTITY в качестве нового идентификатора клиента. Затем вы можете разместить заказ для новой учетной записи, указав сумму и дату заказа, а затем нажмите кнопку "Разместить заказ ".
Создать автогенерируемые обработчики событий для формы NewCustomer
Создайте пустой обработчик событий Click для каждой кнопки в форме NewCustomer, дважды щелкнув каждую из четырех кнопок. Дважды щелкнув кнопки, также добавляет автоматически созданный код в файл кода конструктора, который позволяет нажать кнопку для создания события.
Добавление кода для логики формы NewCustomer
Чтобы завершить логику формы NewCustomer, выполните следующие действия:
Включите пространство имен
System.Data.SqlClientв область видимости, чтобы вам не нужно было полностью указывать имена его членов.
Добавьте в класс некоторые переменные и вспомогательные методы.
// 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; }
Заполните тела метода для четырех обработчиков событий выбора кнопки.
/// <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(); }
Форма FillOrCancel
Форма FillOrCancel запускает запрос для возврата заказа при вводе идентификатора заказа, а затем нажмите кнопку "Найти заказ ". Возвращаемая строка отображается в сетке данных только для чтения. Вы можете пометить заказ как отмененный (X), если нажмите кнопку "Отмена заказа ", или вы можете пометить заказ как заполненный (F) при нажатии кнопки "Заполнить заказ ". Если снова выбрать кнопку "Найти заказ ", появится обновленная строка.
Создайте автогенерированные обработчики событий для формы FillOrCancel
Создайте пустые обработчики событий Click для четырех кнопок в форме FillOrCancel, дважды щелкнув кнопки. Дважды щелкнув кнопки, также добавляет автоматически созданный код в файл кода конструктора, который позволяет нажать кнопку для создания события.
Добавление кода для логики формы FillOrCancel
Чтобы завершить логику формы FillOrCancel, выполните следующие действия.
Подключите следующие два пространства имен к области видимости, чтобы не нужно было полностью квалифицировать имена их элементов.
Добавьте в класс переменную и вспомогательный метод.
// 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; } }
Заполните тела метода для четырех обработчиков событий выбора кнопки.
/// <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(); }
Тестирование приложения
Запустите приложение и попробуйте создать несколько клиентов и заказов, чтобы убедиться, что все работает должным образом.
Чтобы убедиться, что база данных обновлена с изменениями, выполните следующие действия.
Откройте узел таблиц в обозревателе серверов.
Щелкните правой кнопкой мыши узлы "Клиенты и заказы " и выберите "Показать данные таблицы".