共用方式為


使用 Visual Studio 將物件繫結為 .NET Framework 應用程式中的資料來源

注意

資料集和相關類別是 2000 年代初的舊版 .NET Framework 技術,可讓應用程式在應用程式與資料庫中斷連線時使用記憶體中的資料。 它們特別適用於可讓使用者修改資料並將變更保存回資料庫的應用程式。 雖然已證明資料集是非常成功的技術,但建議新的 .NET 應用程式使用 Entity Framework Core。 Entity Framework 提供更自然的方式,將表格式資料作為物件模型使用,而且具有更簡單的程式設計介面。

Visual Studio 提供設計階段工具,用於將自訂物件當作應用程式中的資料來源使用。 當您想要將資料從資料庫儲存在繫結至 UI 控制項的物件中時,建議的方法是使用 Entity Framework 來產生一個或多個類別。 Entity Framework 會自動產生所有樣板變更追蹤程式碼,這表示當您在 DbSet 物件上呼叫 AcceptChanges 時,本機物件的任何變更都會自動保存至資料庫。 如需詳細資訊,請參閱 Entity Framework 文件

提示

只有在您的應用程式已經以資料集為基礎時,才應該考慮本文中物件繫結的方法。 若您已熟悉資料集,而且您將要處理的資料是表格式,而且不太複雜或太大,您也可以使用這些方法。 如需更簡單的範例,其中涉及使用 DataReader 直接將資料載入物件中,以及在沒有資料繫結的情況下手動更新 UI,請參閱 使用 ADO.NET 建立簡單的資料應用程式

物件需求

自訂物件使用 Visual Studio 中資料設計工具的唯一需求是物件至少需要一個公用屬性。

一般而言,自訂物件不需要任何特定的介面、建構函式或屬性,做作為應用程式的資料來源。 不過,如果您想要將物件從 [資料來源] 視窗拖曳至設計介面,以建立資料繫結控制項,以及如果物件實作 ITypedListIListSource 介面,物件必須具有預設建構函式。 否則,Visual Studio 無法具現化資料來源物件,而且當您將項目拖曳至設計介面時,其會顯示錯誤。

使用自訂物件做為資料來源的範例

雖然在使用物件做為資料來源時,實作應用程式邏輯的方式不計其數,但對於 SQL 資料庫而言,有幾個標準作業可以使用 Visual Studio 產生的 TableAdapter 物件來簡化。 此頁面說明如何使用 TableAdapters 實作這些標準流程。 其並非旨在做為建立自訂物件的指南。 例如,不論物件或應用程式邏輯的特定實作為何,您通常都會執行下列標準作業:

  • 將資料載入物件中 (通常從資料庫載入)。

  • 建立物件的具型別集合。

  • 將物件新增至集合,以及從集合中移除物件。

  • 在表單上向使用者顯示物件資料。

  • 變更/編輯物件中的資料。

  • 將資料從物件儲存回資料庫。

將資料載入物件中

針對此範例,您會使用 TableAdapters 將資料載入物件中。 根據預設,TableAdapters 是使用兩種方法建立的,這些方法會從資料庫擷取資料並將其填入資料表。

  • TableAdapter.Fill 方法會將傳回的資料填入現有的資料表。

  • TableAdapter.GetData 方法會傳回填入資料的新資料表。

使用資料載入自訂物件的最簡單方式是呼叫 TableAdapter.GetData 方法、反覆執行所傳回資料表中的資料列集合,以及將每個資料列中的值填入每個物件。 您可以建立 GetData 方法,針對新增至 TableAdapter 的任何查詢傳回填入的資料表。

注意

Visual Studio 預設會將 TableAdapter 查詢命名為 FillGetData,但您可以將這些名稱變更為任何有效的方法名稱。

下列範例展示如何反覆執行資料表中的資料列,以及將資料填入物件:

private void LoadCustomers()
{
    NorthwindDataSet.CustomersDataTable customerData = 
        customersTableAdapter1.GetTop5Customers();
    
    foreach (NorthwindDataSet.CustomersRow customerRow in customerData)
    {
        Customer currentCustomer = new Customer();
        currentCustomer.CustomerID = customerRow.CustomerID;
        currentCustomer.CompanyName = customerRow.CompanyName;

        if (customerRow.IsAddressNull() == false)
        {
            currentCustomer.Address = customerRow.Address;
        }

        if (customerRow.IsCityNull() == false)
        {
            currentCustomer.City = customerRow.City;
        }

        if (customerRow.IsContactNameNull() == false)
        {
            currentCustomer.ContactName = customerRow.ContactName;
        }

        if (customerRow.IsContactTitleNull() == false)
        {
            currentCustomer.ContactTitle = customerRow.ContactTitle;
        }

        if (customerRow.IsCountryNull() == false)
        {
            currentCustomer.Country = customerRow.Country;
        }

        if (customerRow.IsFaxNull() == false)
        {
            currentCustomer.Fax = customerRow.Fax;
        }

        if (customerRow.IsPhoneNull() == false)
        {
            currentCustomer.Phone = customerRow.Phone;
        }

        if (customerRow.IsPostalCodeNull() == false)
        {
            currentCustomer.PostalCode = customerRow.PostalCode;
        }

        if (customerRow.IsRegionNull() == false)
        {
            currentCustomer.Region = customerRow.Region;
        }

        LoadOrders(currentCustomer);
        customerBindingSource.Add(currentCustomer);
    }
}

建立物件的具型別集合

您可以為物件建立集合類別,或使用 BindingSource 元件自動提供的具型別集合。

當您要為物件建立自訂集合類別時,建議您繼承自 BindingList<T>。 這個泛型類別提供管理集合的功能,以及可讓系統引發事件,將通知傳送至 Windows Forms 中的資料繫結基礎結構。

BindingSource 中自動產生的集合會針對其具型別的集合使用 BindingList<T>。 如果您的應用程式不需要其他功能,您可以在 BindingSource 內維護您的集合。 如需詳細資訊,請參閱 BindingSource 類別的 List 屬性。

注意

如果您的集合需要 BindingList<T> 基底實作未提供的功能,您應該建立自訂集合,以便可以視需要新增至類別。

下列程式碼展示如何為 Order 物件的強型別集合建立類別:

/// <summary>
/// A collection of Orders
/// </summary>
public class Orders: System.ComponentModel.BindingList<Order>
{
    // Add any additional functionality required by your collection.
}

將物件新增至集合

您可以呼叫自訂集合類別或 BindingSourceAdd 方法,將物件新增至集合。

注意

當您繼承自 BindingList<T> 時,系統會自動為您的自訂集合提供 Add 方法。

下列程式碼展示如何將物件新增至 BindingSource 中的具型別集合:

Customer currentCustomer = new Customer();
customerBindingSource.Add(currentCustomer);

下列程式碼展示如何將物件新增至繼承自 BindingList<T> 的具型別集合:

注意

在此範例中,Orders,集合是 Customer 物件的 屬性。

Order currentOrder = new Order();
currentCustomer.Orders.Add(currentOrder);

從集合中移除物件

您可以呼叫自訂集合類別或 BindingSourceRemoveRemoveAt 方法,從集合中移除物件。

注意

當您繼承自 BindingList<T> 時,系統會自動為您的自訂集合提供 RemoveRemoveAt 方法。

下列程式碼展示如何使用 RemoveAt 方法,從 BindingSource 中的具型別集合中尋找和移除物件:

int customerIndex = customerBindingSource.Find("CustomerID", "ALFKI");
customerBindingSource.RemoveAt(customerIndex);

向使用者顯示物件資料

若要向使用者顯示物件中的資料,請使用 [資料來源設定精靈] 建立物件資料來源,然後從 [資料來源] 視窗將整個物件或個別屬性拖曳到表單上。

修改物件中的資料

在資料繫結至 Windows Forms 控制項的自訂物件中,若要編輯其資料,只需編輯繫結控制項中的資料 (或直接在物件的屬性中編輯)。 資料繫結架構會更新物件中的資料。

如果您的應用程式需要追蹤變更,以及將建議的變更復原至其原始值,則您必須在物件模型中實作這項功能。 如需資料表如何追蹤建議變更的範例,請參閱 DataRowStateHasChangesGetChanges

將物件中的資料儲存回資料庫

將資料儲存回資料庫,方法是將值從您的物件傳遞至 TableAdapter 的 DBDirect 方法。

Visual Studio 會建立可以直接針對資料庫執行的 DBDirect 方法。 這些方法不需要 DataSet 或 DataTable 物件。

TableAdapter DBDirect 方法 描述
TableAdapter.Insert 將新記錄新增至資料庫,這可讓您傳入個別資料行值作為方法參數。
TableAdapter.Update 更新資料庫中的現有記錄。 Update 方法會採用原始和新的資料行值作為方法參數。 原始值用於找出原始記錄,而新的值則用於更新該記錄。

TableAdapter.Update 方法也會用來協調資料集中的變更回到資料庫,方法是採用 DataSetDataTableDataRowDataRow 的陣列作為方法參數。
TableAdapter.Delete 根據做為方法參數傳入的原始資料行值,刪除資料庫中的現有記錄。

若要儲存物件集合中的資料,請反覆執行物件的集合 (例如,使用 for-next 迴圈)。 使用 TableAdapter 的 DBDirect 方法,將每個物件的值傳送至資料庫。

下列範例展示如何使用 TableAdapter.Insert DBDirect 方法,將新的客戶直接新增至資料庫:

private void AddNewCustomers(Customer currentCustomer)
{
    customersTableAdapter.Insert( 
        currentCustomer.CustomerID, 
        currentCustomer.CompanyName, 
        currentCustomer.ContactName, 
        currentCustomer.ContactTitle, 
        currentCustomer.Address, 
        currentCustomer.City, 
        currentCustomer.Region, 
        currentCustomer.PostalCode, 
        currentCustomer.Country, 
        currentCustomer.Phone, 
        currentCustomer.Fax);
}