Поделиться через


Создание простого приложения данных с помощью ADO.NET

Заметка

Наборы данных и связанные классы являются устаревшими технологиями .NET Framework с начала 2000-х годов, которые позволяют приложениям работать с данными в памяти, пока приложения отключены от базы данных. Технологии особенно полезны для приложений, которые позволяют пользователям изменять данные и сохранять изменения обратно в базу данных. Хотя наборы данных оказались очень успешными, мы рекомендуем использовать новые приложения .NET Entity Framework Core. Entity Framework предоставляет более естественный способ работы с табличными данными в виде объектных моделей, и он имеет более простой интерфейс программирования.

При создании приложения, которое управляет данными в базе данных, выполняются основные задачи, такие как определение строк подключения, вставка данных и выполнение хранимых процедур. Следуя этому разделу, вы можете узнать, как взаимодействовать с базой данных в простом приложении Windows Forms, использующем концепцию "forms over data", с помощью Visual C# или Visual Basic и ADO.NET. Все технологии данных .NET, включая наборы данных, LINQ to SQL и Entity Framework, в конечном счете выполняют действия, которые очень похожи на приведенные в этой статье.

В этой статье демонстрируется простой способ быстрого получения данных из базы данных. Если приложению необходимо изменить данные в нетривиальных способах и обновить базу данных, следует рассмотреть возможность использования Entity Framework и использования привязки данных для автоматической синхронизации элементов управления пользовательским интерфейсом с изменениями в базовых данных.

Важный

Чтобы код оставался простым, он не включает обработку исключений, готовую для использования в производственной среде.

Заметка

Полный код для этого руководства можно получить в репозитории документации Visual Studio на GitHub в C# и Visual Basic.

Необходимые условия

Чтобы создать приложение, вам потребуется:

  • Visual Studio с установленными рабочими нагрузками разработки классических приложений .NET и хранилища данных и обработки рабочих нагрузок. Чтобы установить их, откройте Установщик Visual Studio и выберите Изменить (или Дополнительно>Изменить) рядом с версией Visual Studio, которую вы хотите изменить.

  • SQL Server Express LocalDB. Если у вас нет SQL Server Express LocalDB, его можно установить на странице загрузки SQL Server.

В этом разделе предполагается, что вы знакомы с основными функциями интегрированной среды разработки Visual Studio и можете создавать приложения Windows Forms, добавлять формы в проект, помещать кнопки и другие элементы управления в формы, задавать свойства элементов управления и кодировать простые события. Если вы не знакомы с этими задачами, мы рекомендуем выполнить создание приложения Windows Forms в Visual Studio с помощью руководства по Visual Basic или создание приложения Windows Forms в Visual Studio с помощью C#, прежде чем начать это пошаговое руководство.

Настройте образец базы данных

Создайте образец базы данных, выполнив следующие действия.

  1. В Visual Studio откройте окно обозревателя серверов.

  2. Щелкните правой кнопкой мыши Подключения к данным и выберите Создать базу данных SQL Server.

  3. В текстовом поле имени сервера введите (localdb)\mssqllocaldb.

  4. В текстовом поле Имя новой базы данных введитеSales, а затем нажмите кнопку ОК.

    Пустая база данных sales создается и добавляется в узел "Подключения к данным" в обозревателе серверов.

  5. Щелкните правой кнопкой мыши подключение к данным Sales и выберите "Создать запрос".

    Откроется окно редактора запросов.

  6. Скопируйте скрипт Transact-SQL продаж в буфер обмена.

  7. Вставьте скрипт T-SQL в редактор запросов, затем нажмите кнопку Выполнить.

    Через некоторое время запрос завершает выполнение и создаются объекты базы данных. База данных содержит две таблицы: Customer и Orders. Эти таблицы изначально не содержат данных, но при запуске создаваемого приложения можно добавить данные. База данных также содержит четыре простых хранимых процедуры.

Создание форм и добавление элементов управления

  1. Создайте проект C# или Visual Basic с помощью шаблона приложения Windows Forms (.NET Framework), а затем присвойте ему имя SimpleDataApp.

    Visual Studio создает проект и несколько файлов, включая пустую форму Windows, которая называется Form1.

  2. Добавьте в проект две формы Windows Forms, чтобы она получила три формы, а затем присвойте им следующие имена:

    • Навигация

    • НовыйКлиент

    • ЗаполнитьИлиОтменить

  3. Для каждой формы добавьте текстовые поля, кнопки и другие элементы управления, которые отображаются на следующих рисунках. Для каждого элемента управления задайте свойства, описываемые таблицами.

    Заметка

    Поле группы и элементы управления метками добавляют ясность, но не используются в коде.

    форма навигации

    диалоговое окно навигации

Элементы управления для формы навигации Свойства
Кнопка Name = btnGoToAdd
Кнопка Name = btnGoToFillOrCancel
Кнопка Name = btnExit

форма НовыйКлиент

Добавление нового клиента и размещение заказа

Элементы управления для формы NewCustomer Свойства
Текстовое поле Name = txtCustomerName
Текстовое поле Name = txtCustomerID

Только для чтения = Истина
Кнопка Name = btnCreateAccount
Числовой счётчик DecimalPlaces = 0

Максимум = 5000

Имя = numOrderAmount
DateTimePicker Формат = Краткий

Name = dtpOrderDate
Кнопка Name = btnPlaceOrder
Кнопка Name = btnAddAnotherAccount
Кнопка Name = btnAddFinish

форма ЗаполнитьИлиОтменить

заполнение или отмена заказов

Элементы управления для формы FillOrCancel Свойства
Текстовое поле Name = txtOrderID
Кнопка Name = btnFindByOrderID
DateTimePicker Формат = Краткий

Name = dtpFillDate
DataGridView Name = dgvCustomerOrders

Только для чтения = Истина

ВидимостьЗаголовковСтрок = Ложь
Кнопка Name = btnCancelOrder
Кнопка Name = btnFillOrder
Кнопка Name = btnFinishUpdates

Сохранение строки подключения

Когда приложение пытается открыть подключение к базе данных, приложение должно иметь доступ к строке подключения. Чтобы избежать ввода строки вручную в каждой форме, сохраните строку в файле App.config в проекте и создайте метод, возвращающий строку при вызове метода из любой формы в приложении.

Строку подключения можно найти, щелкнув правой кнопкой мыши подключение к данным Sales в обозревателе серверов и выбрав Свойства. Найдите свойство ConnectionString, а затем используйте клавиши Ctrl+A, Ctrl+C, чтобы выделить строку и скопировать её в буфер обмена.

  1. Если вы используете C#, в обозревателя решенийразверните узел свойств в проекте, а затем откройте файл Settings.settings. Если вы используете Visual Basic, в Solution Explorerщелкните Show All Files, разверните узел My Project, а затем откройте файл Settings.settings.

  2. В столбце имени введите connString.

  3. В списке типа выберите (строка подключения).

  4. В списке области выберите Приложение.

  5. В столбце значений введите строку подключения (без внешних кавычек), а затем сохраните изменения.

    Снимок экрана строки подключения в Settings.settings

Осторожность

В реальном приложении необходимо безопасно хранить строку подключения, как описано в разделе строки подключения и файлы конфигурации. Для обеспечения оптимальной безопасности используйте метод проверки подлинности, который не зависит от хранения пароля в строке подключения, например проверки подлинности Windows для локальной базы данных SQL Server. См. Сохранение и Изменение строк подключения.

Написание кода для форм

В этом разделе содержатся краткие сведения о том, что делает каждая форма. Он также предоставляет код, определяющий базовую логику при нажатии кнопки в форме.

При запуске приложения откроется форма навигации. Кнопка Добавить учетную запись открывает форму NewCustomer. Кнопка "Заливка или отмена заказов" открывает форму FillOrCancel. Кнопка выхода закрывает приложение.

Сделайте форму навигации формой запуска

Если вы используете C#, в обозревателе решенийоткройте Program.csи измените строку Application.Run на следующее: Application.Run(new Navigation());

Если вы используете Visual Basic, в обозревателе решений откройте окно свойств , перейдите на вкладку приложение и выберите SimpleDataApp.Navigation в списке формы запуска.

Создайте автоматически генерируемые обработчики событий

Дважды щелкните три кнопки в форме навигации, чтобы создать пустые методы обработчика событий. Дважды щелкнув кнопки, также добавляет автоматически созданный код в файл кода конструктора, который позволяет нажатию кнопки вызывать событие.

Заметка

Если вы пропустите действие двойного щелчка в конструкторе и просто скопируйте код и вставьте его в файлы кода, не забудьте задать обработчик событий правильным методом. Это можно сделать в окне "Свойства". Перейдите на вкладку события (используйте кнопку панели инструментов молнии) и найдите обработчик 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();
}

Заметка

Код для этого руководства доступен в C# и Visual Basic. Чтобы переключить язык кода на этой странице между C# и Visual Basic, используйте переключатель языка кода в верхней части каждого примера кода.

Форма нового клиента

При вводе имени клиента и нажатии кнопки "Создать учетную запись" форма NewCustomer создает учетную запись клиента, а SQL Server возвращает значение IDENTITY в качестве нового идентификатора клиента. Затем вы можете оформить заказ для новой учетной записи, указав сумму и дату заказа и нажав кнопку Разместить заказ.

Создать автоматически создаваемые обработчики событий

Создайте пустой обработчик событий Click для каждой кнопки в форме NewCustomer, дважды щелкнув каждую из четырех кнопок. Двойной щелчок по кнопкам также добавляет автоматически сгенерированный код в файл кода конструктора, который позволяет вызов события при нажатии кнопки.

Добавление кода для логики формы NewCustomer

Чтобы завершить логику формы NewCustomer, выполните следующие действия.

  1. Подключите пространство имен System.Data.SqlClient, чтобы вам не нужно было полностью квалифицировать имена его членов.

    using System.Data.SqlClient;
    
  2. Добавьте в класс некоторые переменные и вспомогательные методы, как показано в следующем коде.

    // 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;
    }
    
  3. Реализуйте блоки кода метода для четырех обработчиков событий нажатия кнопки, как показано в следующем коде.

    /// <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) при нажатии кнопки заполнения заказа. Если снова выбрать кнопку "Найти порядок", появится обновленная строка.

Создание автоматически генерируемых обработчиков событий

Создайте пустые обработчики событий Click для четырех кнопок в форме FillOrCancel, дважды щелкнув кнопки. Двойной щелчок на кнопке также добавляет автоматически сгенерированный код в файл кода конструктора, который позволяет нажатию кнопки вызывать событие.

Добавление кода для логики формы FillOrCancel

Чтобы завершить логику формы FillOrCancel, выполните следующие действия.

  1. Подключите следующие два пространства имен к области видимости, чтобы не нужно было полностью квалифицировать имена их элементов.

    using System.Data.SqlClient;
    using System.Text.RegularExpressions;
    
  2. Добавьте в класс переменную и вспомогательный метод, как показано в следующем коде.

    // 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;
        }
    }
    
  3. Дополните код методов для четырех обработчиков событий клика по кнопке, как показано в следующем коде.

    /// <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();
    }
    

Тестирование приложения

Запустите приложение и попробуйте создать несколько клиентов и заказов, чтобы убедиться, что все работает должным образом. Чтобы убедиться, что база данных обновлена вашими изменениями, откройте узел Таблицы в Обозреватель серверов, щелкните правой кнопкой мыши на узлы Клиенты и Заказы, и выберите Показать данные таблицы.