Vytvoření jednoduché datové aplikace pomocí ADO.NET

Poznámka:

Datové sady a související třídy jsou staršími technologiemi rozhraní .NET Framework z počátku 2000, které aplikacím umožňují pracovat s daty v paměti, zatímco aplikace jsou odpojené od databáze. Jsou zvláště užitečné pro aplikace, které uživatelům umožňují upravovat data a uchovávat změny zpět do databáze. I když se datové sady ukázaly jako velmi úspěšná technologie, doporučujeme, aby nové aplikace .NET používaly Entity Framework Core. Entity Framework poskytuje přirozenější způsob práce s tabulkovými daty jako objektovými modely a má jednodušší programovací rozhraní.

Při vytváření aplikace, která manipuluje s daty v databázi, provádíte základní úlohy, jako je definování připojovací řetězec, vkládání dat a spouštění uložených procedur. V tomto tématu můžete zjistit, jak pracovat s databází v rámci jednoduché model Windows Forms "formuláře přes data" pomocí jazyka Visual C# nebo Visual Basic a ADO.NET. Všechny datové technologie .NET, včetně datových sad, LINQ to SQL a Entity Framework, nakonec provádějí kroky, které jsou velmi podobné těm, které jsou uvedené v tomto článku.

Tento článek ukazuje jednoduchý způsob, jak rychle získat data z databáze. Pokud vaše aplikace potřebuje upravit data netriviálními způsoby a aktualizovat databázi, měli byste zvážit použití entity Framework a použití datové vazby k automatické synchronizaci ovládacích prvků uživatelského rozhraní na změny v podkladových datech.

Důležité

Aby byl kód jednoduchý, nezahrnuje zpracování výjimek připravené pro produkční prostředí.

Poznámka:

Úplný kód pro tento kurz je přístupný v úložišti GitHubu v sadě Visual Studio v jazyce C# a Visual Basic.

Požadavky

K vytvoření aplikace potřebujete:

  • Sada Visual Studio s nainstalovanými úlohami vývoje desktopových aplikací .NET a ukládáním dat a zpracováním dat Pokud je chcete nainstalovat, otevřete Instalační program pro Visual Studio a zvolte Upravit (nebo Další>úpravy) vedle verze sady Visual Studio, kterou chcete upravit.

  • SQL Server Express LocalDB. Pokud nemáte SQL Server Express LocalDB, můžete ji nainstalovat ze stránky pro stažení SQL Serveru.

V tomto tématu se předpokládá, že znáte základní funkce integrovaného vývojového prostředí sady Visual Studio a můžete vytvořit model Windows Forms aplikaci, přidat do projektu formuláře, vložit tlačítka a další ovládací prvky do formulářů, nastavit vlastnosti ovládacích prvků a jednoduché události kódu. Pokud s těmito úlohami nejste obeznámeni, doporučujeme před zahájením tohoto návodu dokončit aplikaci Vytvořit model Windows Forms v sadě Visual Studio pomocí visual basicunebo vytvořit aplikaci model Windows Forms v sadě Visual Studio s jazykem C#.

Vytvoření ukázkové databáze

Ukázkovou databázi vytvořte následujícím postupem:

  1. V sadě Visual Studio otevřete okno Průzkumníka serveru.

  2. Klikněte pravým tlačítkem na Datové Připojení iony a zvolte Vytvořit novou databázi SQL Serveru.

  3. Do textového pole Název serveru zadejte (localdb)\mssqllocaldb.

  4. Do textového pole Nový název databáze zadejte Sales a pak zvolte OK.

    Prázdná databáze Sales se vytvoří a přidá do uzlu Data Připojení ions v Průzkumníku serveru.

  5. Klikněte pravým tlačítkem na datové připojení Sales (Prodej ) a vyberte New Query (Nový dotaz).

    Otevře se okno editoru dotazů.

  6. Zkopírujte skript Sales Transact-SQL do schránky.

  7. Vložte skript T-SQL do editoru dotazů a pak zvolte tlačítko Spustit .

    Po krátké době se dotaz dokončí a vytvoří se databázové objekty. Databáze obsahuje dvě tabulky: Customer (Zákazník) a Orders (Objednávky). Tyto tabulky zpočátku neobsahují žádná data, ale data můžete přidat při spuštění aplikace, kterou vytvoříte. Databáze obsahuje také čtyři jednoduché uložené procedury.

Vytvoření formulářů a přidání ovládacích prvků

  1. Vytvořte projekt jazyka C# nebo Visual Basic pomocí šablony model Windows Forms App (.NET Framework) a pojmenujte ho SimpleDataApp.

    Visual Studio vytvoří projekt a několik souborů, včetně prázdného formuláře Windows s názvem Form1.

  2. Přidejte do projektu dva formuláře Windows, aby měly tři formuláře, a pak jim dejte následující názvy:

    • Navigace

    • NewCustomer

    • FillOrCancel

  3. Pro každý formulář přidejte textová pole, tlačítka a další ovládací prvky, které se zobrazí na následujících ilustracích. Pro každý ovládací prvek nastavte vlastnosti, které tabulky popisují.

    Poznámka:

    Pole skupiny a ovládací prvky popisku přidávají přehlednost, ale v kódu se nepoužívají.

    Navigační formulář

    Dialogové okno Navigace

Ovládací prvky pro navigační formulář Vlastnosti
Tlačítko Name = btnGoToAdd
Tlačítko Name = btnGoToFillOrCancel
Tlačítko Name = btnExit

Formulář NewCustomer

Přidání nového zákazníka a zadání objednávky

Ovládací prvky formuláře NewCustomer Vlastnosti
TextBox Name = txtCustomerName
TextBox Name = txtCustomerID

Readonly = True
Tlačítko Name = btnCreateAccount
Numericupdown Desetinná místa = 0

Maximum = 5000

Name = numOrderAmount
Datetimepicker Format = Short

Name = dtpOrderDate
Tlačítko Name = btnPlaceOrder
Tlačítko Name = btnAddAnotherAccount
Tlačítko Name = btnAddFinish

Formulář FillOrCancel

vyplnění nebo zrušení objednávek

Ovládací prvky formuláře FillOrCancel Vlastnosti
TextBox Name = txtOrderID
Tlačítko Name = btnFindByOrderID
Datetimepicker Format = Short

Name = dtpFillDate
Datagridview Name = dgvCustomerOrders

Readonly = True

RowHeadersVisible = False
Tlačítko Name = btnCancelOrder
Tlačítko Name = btnFillOrder
Tlačítko Name = btnFinish Aktualizace

Uložení připojovací řetězec

Když se aplikace pokusí otevřít připojení k databázi, musí mít aplikace přístup k připojovací řetězec. Chcete-li se vyhnout ručnímu zadávání řetězce v každém formuláři, uložte řetězec do souboru App.config v projektu a vytvořte metodu, která vrátí řetězec při zavolání metody z libovolného formuláře v aplikaci.

Připojovací řetězec najdete tak, že v Průzkumníku serveru kliknete pravým tlačítkem na datové připojení Sales a zvolíte Vlastnosti. Vyhledejte vlastnost Připojení ionString a pak pomocí ctrl+A, Ctrl+C vyberte a zkopírujte řetězec do schránky.

  1. Pokud používáte jazyk C#, v Průzkumník řešení rozbalte uzel Vlastnosti v projektu a otevřete soubor Nastavení.settings. Pokud používáte Visual Basic, klikněte v Průzkumník řešení na Zobrazit všechny soubory, rozbalte uzel Můj projekt a otevřete soubor Nastavení.settings.

  2. Do sloupce Název zadejte connString.

  3. V seznamu Typ vyberte (Připojení ion String).

  4. V seznamu Obor vyberte Možnost Aplikace.

  5. Do sloupce Hodnota zadejte připojovací řetězec (bez uvozovek) a uložte provedené změny.

    Snímek obrazovky s řetězcem Připojení ion v Nastavení.settings

Poznámka:

Ve skutečné aplikaci byste měli bezpečně uložit připojovací řetězec, jak je popsáno v Připojení ionových řetězcích a konfiguračních souborech.

Napsání kódu pro formuláře

Tato část obsahuje stručné přehledy toho, co jednotlivé formuláře dělá. Poskytuje také kód, který definuje základní logiku při kliknutí na tlačítko ve formuláři.

Při spuštění aplikace se otevře navigační formulář. Tlačítko Přidat účet otevře formulář NewCustomer. Tlačítko Vyplnit nebo zrušit objednávky otevře formulář FillOrCancel. Tlačítko Ukončit zavře aplikaci.

Nastavení formuláře navigace jako spouštěcího formuláře

Pokud používáte jazyk C#, otevřete v Průzkumník řešení Program.cs a změňte Application.Run řádek na tento:Application.Run(new Navigation());

Pokud používáte Visual Basic, otevřete v Průzkumník řešení okno Vlastnosti, vyberte kartu Aplikace a pak v seznamu formuláře Po spuštění vyberte SimpleDataApp.Navigation.

Vytváření automaticky vygenerovaných obslužných rutin událostí

Poklikejte na tři tlačítka na navigačním formuláři a vytvořte prázdné metody obslužné rutiny události. Poklikáním na tlačítka přidáte do souboru kódu Návrháře také automaticky vygenerovaný kód, který umožňuje kliknutím na tlačítko vyvolat událost.

Poznámka:

Pokud v návrháři přeskočíte akci poklikání a zkopírujete kód a vložíte ho do souborů kódu, nezapomeňte nastavit obslužnou rutinu události na správnou metodu. Můžete to udělat v okně Vlastnosti . Přepněte na kartu Události (použijte tlačítko panelu nástrojů blesku) a vyhledejte obslužnou rutinu kliknutí .

Přidání kódu pro logiku navigačního formuláře

Na stránce kódu pro navigační formulář vyplňte těla metody pro tři obslužné rutiny událostí kliknutí na tlačítko, jak je znázorněno v následujícím kódu.

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

Poznámka:

Kód pro tento kurz je k dispozici v jazyce C# a Visual Basic. Pokud chcete přepnout jazyk kódu na této stránce mezi jazykem C# a Visual Basicem, použijte přepínač jazyka kódu v horní části každého příkladu kódu.

Formulář NewCustomer

Když zadáte jméno zákazníka a pak vyberete tlačítko Vytvořit účet , formulář NewCustomer vytvoří účet zákazníka a SQL Server vrátí hodnotu IDENTITY jako nové ID zákazníka. Objednávku nového účtu pak můžete zadat zadáním částky a data objednávky a výběrem tlačítka Odeslat objednávku.

Vytváření automaticky vygenerovaných obslužných rutin událostí

Vytvořte prázdnou obslužnou rutinu události Click pro každé tlačítko ve formuláři NewCustomer poklikáním na každé ze čtyř tlačítek. Poklikáním na tlačítka přidáte do souboru kódu Návrháře také automaticky vygenerovaný kód, který umožňuje kliknutím na tlačítko vyvolat událost.

Přidání kódu pro logiku formuláře NewCustomer

K dokončení logiky formuláře NewCustomer postupujte takto.

  1. System.Data.SqlClient Přeneste obor názvů do oboru, abyste nemuseli plně opravovat názvy jejích členů.

    using System.Data.SqlClient;
    
  2. Přidejte do třídy některé proměnné a pomocné metody, jak je znázorněno v následujícím kódu.

    // 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. Dokončete těla metody pro čtyři obslužné rutiny událostí kliknutí na tlačítko, jak je znázorněno v následujícím kódu.

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

Formulář FillOrCancel

Formulář FillOrCancel spustí dotaz, který vrátí objednávku, když zadáte ID objednávky a potom kliknete na tlačítko Najít objednávku. Vrácený řádek se zobrazí v datové mřížce jen pro čtení. Objednávku můžete označit jako zrušenou (X), pokud vyberete tlačítko Zrušit objednávku, nebo můžete objednávku označit jako vyplněnou (F), pokud vyberete tlačítko Vyplnit objednávku. Pokud znovu vyberete tlačítko Najít objednávku , zobrazí se aktualizovaný řádek.

Vytváření automaticky vygenerovaných obslužných rutin událostí

Vytvořte prázdné obslužné rutiny události Click pro čtyři tlačítka ve formuláři FillOrCancel poklikáním na tlačítka. Poklikáním na tlačítka přidáte do souboru kódu Návrháře také automaticky vygenerovaný kód, který umožňuje kliknutím na tlačítko vyvolat událost.

Přidání kódu pro logiku formuláře FillOrCancel

Chcete-li dokončit logiku formuláře FillOrCancel, postupujte takto.

  1. Přineste následující dva obory názvů do oboru, abyste nemuseli plně kvalifikovat názvy jejich členů.

    using System.Data.SqlClient;
    using System.Text.RegularExpressions;
    
  2. Přidejte do třídy proměnnou a pomocnou metodu, jak je znázorněno v následujícím kódu.

    // 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. Dokončete těla metody pro čtyři obslužné rutiny událostí kliknutí na tlačítko, jak je znázorněno v následujícím kódu.

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

Otestování aplikace

Spusťte aplikaci a zkuste vytvořit několik zákazníků a objednávek, abyste ověřili, že všechno funguje podle očekávání. Pokud chcete ověřit, že se databáze aktualizuje o provedené změny, otevřete uzel Tabulky v Průzkumníku serveru, klikněte pravým tlačítkem na uzly Zákazníci a Objednávky a zvolte Zobrazit data tabulky.