DataTable.Load DataTable.Load DataTable.Load DataTable.Load Method

定義

使用所提供的 DataTable,用資料來源的值填滿 IDataReaderFills a DataTable with values from a data source using the supplied IDataReader. 如果 DataTable 已經包含資料列,從資料來源傳入的資料會與現有的資料列合併。If the DataTable already contains rows, the incoming data from the data source is merged with the existing rows.

多載

Load(IDataReader) Load(IDataReader) Load(IDataReader) Load(IDataReader)

使用所提供的 DataTable,用資料來源的值填滿 IDataReaderFills a DataTable with values from a data source using the supplied IDataReader. 如果 DataTable 已經包含資料列,從資料來源傳入的資料會與現有的資料列合併。If the DataTable already contains rows, the incoming data from the data source is merged with the existing rows.

Load(IDataReader, LoadOption) Load(IDataReader, LoadOption) Load(IDataReader, LoadOption)

使用所提供的 DataTable,用資料來源的值填滿 IDataReaderFills a DataTable with values from a data source using the supplied IDataReader. 如果 DataTable 已經包含資料列,從資料來源傳入的資料會根據 loadOption 參數的值,與現有的資料列合併。If the DataTable already contains rows, the incoming data from the data source is merged with the existing rows according to the value of the loadOption parameter.

Load(IDataReader, LoadOption, FillErrorEventHandler) Load(IDataReader, LoadOption, FillErrorEventHandler) Load(IDataReader, LoadOption, FillErrorEventHandler)

使用所提供的 DataTable,以資料來源的值填滿 IDataReader,使用錯誤處理委派。Fills a DataTable with values from a data source using the supplied IDataReader using an error-handling delegate.

範例

下列範例示範呼叫Load方法時所牽涉到的幾個問題。The following example demonstrates several of the issues involved with calling the Load method. 首先,此範例著重于架構問題,包括從載入IDataReader的中推斷架構,然後處理不相容的架構,以及遺漏或其他資料行的架構。First, the example focuses on schema issues, including inferring a schema from the loaded IDataReader, and then handling incompatible schemas, and schemas with missing or additional columns. 然後,此範例會著重于資料問題,包括處理各種載入選項。The example then focuses on data issues, including handling the various loading options.

注意

這個範例會示範如何使用的多載版本LoadThis example shows how to use one of the overloaded versions of Load. 如需其他可能可用的範例,請參閱個別多載主題。For other examples that might be available, see the individual overload topics.

static void Main()
{
    // This example examines a number of scenarios involving the 
    // DataTable.Load method.
    Console.WriteLine("Load a DataTable and infer its schema:");

    // The table has no schema. The Load method will infer the 
    // schema from the IDataReader:
    DataTable table = new DataTable();

    // Retrieve a data reader, based on the Customers data. In
    // an application, this data might be coming from a middle-tier
    // business object:
    DataTableReader reader = new DataTableReader(GetCustomers());

    table.Load(reader);
    PrintColumns(table);

    Console.WriteLine(" ============================= ");
    Console.WriteLine("Load a DataTable from an incompatible IDataReader:");

    // Create a table with a single integer column. Attempt
    // to load data from a reader with a schema that is 
    // incompatible. Note the exception, determined
    // by the particular incompatibility:
    table = GetIntegerTable();
    reader = new DataTableReader(GetStringTable());
    try
    {
        table.Load(reader);
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.GetType().Name + ":" + ex.Message);
    }

    Console.WriteLine(" ============================= ");
    Console.WriteLine(
        "Load a DataTable with an IDataReader that has extra columns:");

    // Note that loading a reader with extra columns adds
    // the columns to the existing table, if possible:
    table = GetIntegerTable();
    reader = new DataTableReader(GetCustomers());
    table.Load(reader);
    PrintColumns(table);

    Console.WriteLine(" ============================= ");
    Console.WriteLine(
        "Load a DataTable with an IDataReader that has missing columns:");

    // Note that loading a reader with missing columns causes 
    // the columns to be filled with null data, if possible:
    table = GetCustomers();
    reader = new DataTableReader(GetIntegerTable());
    table.Load(reader);
    PrintColumns(table);

    // Demonstrate the various possibilites when loading data into
    // a DataTable that already contains data.
    Console.WriteLine(" ============================= ");
    Console.WriteLine("Demonstrate data considerations:");
    Console.WriteLine("Current value, Original value, (RowState)");
    Console.WriteLine(" ============================= ");
    Console.WriteLine("Original table:");

    table = SetupModifiedRows();
    DisplayRowState(table);

    Console.WriteLine(" ============================= ");
    Console.WriteLine("Data in IDataReader to be loaded:");
    DisplayRowState(GetChangedCustomers());

    PerformDemo(LoadOption.OverwriteChanges);
    PerformDemo(LoadOption.PreserveChanges);
    PerformDemo(LoadOption.Upsert);

    Console.WriteLine("Press any key to continue.");
    Console.ReadKey();
}

private static void DisplayRowState(DataTable table)
{
    for (int i = 0; i <= table.Rows.Count - 1; i++)
    {
        object current = "--";
        object original = "--";
        DataRowState rowState = table.Rows[i].RowState;

        // Attempt to retrieve the current value, which doesn't exist
        // for deleted rows:
        if (rowState != DataRowState.Deleted)
        {
            current = table.Rows[i]["Name", DataRowVersion.Current];
        }

        // Attempt to retrieve the original value, which doesn't exist
        // for added rows:
        if (rowState != DataRowState.Added)
        {
            original = table.Rows[i]["Name", DataRowVersion.Original];
        }
        Console.WriteLine("{0}: {1}, {2} ({3})", i, current, 
            original, rowState);
    }
}

private static DataTable GetChangedCustomers()
{
    // Create sample Customers table.
    DataTable table = new DataTable();

    // Create two columns, ID and Name.
    DataColumn idColumn = table.Columns.Add("ID", typeof(int));
    table.Columns.Add("Name", typeof(string));

    // Set the ID column as the primary key column.
    table.PrimaryKey = new DataColumn[] { idColumn };

    table.Rows.Add(new object[] { 0, "XXX" });
    table.Rows.Add(new object[] { 1, "XXX" });
    table.Rows.Add(new object[] { 2, "XXX" });
    table.Rows.Add(new object[] { 3, "XXX" });
    table.Rows.Add(new object[] { 4, "XXX" });
    table.AcceptChanges();
    return table;
}

private static DataTable GetCustomers()
{
    // Create sample Customers table, in order
    // to demonstrate the behavior of the DataTableReader.
    DataTable table = new DataTable();

    // Create two columns, ID and Name.
    DataColumn idColumn = table.Columns.Add("ID", typeof(int));
    table.Columns.Add("Name", typeof(string));

    // Set the ID column as the primary key column.
    table.PrimaryKey = new DataColumn[] { idColumn };

    table.Rows.Add(new object[] { 0, "Mary" });
    table.Rows.Add(new object[] { 1, "Andy" });
    table.Rows.Add(new object[] { 2, "Peter" });
    table.AcceptChanges();
    return table;
}

private static DataTable GetIntegerTable()
{
    // Create sample Customers table, in order
    // to demonstrate the behavior of the DataTableReader.
    DataTable table = new DataTable();

    // Create two columns, ID and Name.
    DataColumn idColumn = table.Columns.Add("ID", typeof(int));

    // Set the ID column as the primary key column.
    table.PrimaryKey = new DataColumn[] { idColumn };

    table.Rows.Add(new object[] { 4 });
    table.Rows.Add(new object[] { 5 });
    table.AcceptChanges();
    return table;
}

private static DataTable GetStringTable()
{
    // Create sample Customers table, in order
    // to demonstrate the behavior of the DataTableReader.
    DataTable table = new DataTable();

    // Create two columns, ID and Name.
    DataColumn idColumn = table.Columns.Add("ID", typeof(string));

    // Set the ID column as the primary key column.
    table.PrimaryKey = new DataColumn[] { idColumn };

    table.Rows.Add(new object[] { "Mary" });
    table.Rows.Add(new object[] { "Andy" });
    table.Rows.Add(new object[] { "Peter" });
    table.AcceptChanges();
    return table;
}

private static void PerformDemo(LoadOption optionForLoad)
{

    // Load data into a DataTable, retrieve a DataTableReader containing
    // different data, and call the Load method. Depending on the
    // LoadOption value passed as a parameter, this procedure displays
    // different results in the DataTable.
    Console.WriteLine(" ============================= ");
    Console.WriteLine("table.Load(reader, {0})", optionForLoad);
    Console.WriteLine(" ============================= ");

    DataTable table = SetupModifiedRows();
    DataTableReader reader = new DataTableReader(GetChangedCustomers());
    table.RowChanging +=new DataRowChangeEventHandler(HandleRowChanging);

    table.Load(reader, optionForLoad);
    Console.WriteLine();
    DisplayRowState(table);
}

private static void PrintColumns(DataTable table)
{
    // Loop through all the rows in the DataTableReader
    foreach (DataRow row in table.Rows)
    {
        for (int i = 0; i < table.Columns.Count; i++)
        {
            Console.Write(row[i] + " ");
        }
        Console.WriteLine();
    }
}

private static DataTable SetupModifiedRows()
{
    // Fill a DataTable with customer info, and 
    // then modify, delete, and add rows.

    DataTable table = GetCustomers();
    // Row 0 is unmodified.
    // Row 1 is modified.
    // Row 2 is deleted.
    // Row 3 is added.
    table.Rows[1]["Name"] = "Sydney";
    table.Rows[2].Delete();
    DataRow row = table.NewRow();
    row["ID"] = 3;
    row["Name"] = "Melony";
    table.Rows.Add(row);

    // Note that the code doesn't call
    // table.AcceptChanges()
    return table;
}

static void HandleRowChanging(object sender, DataRowChangeEventArgs e)
{
    Console.WriteLine(
        "RowChanging event: ID = {0}, action = {1}", e.Row["ID"], 
        e.Action);
}
Sub Main()
  Dim table As New DataTable()

  ' This example examines a number of scenarios involving the 
  ' DataTable.Load method.
  Console.WriteLine("Load a DataTable and infer its schema:")

  ' Retrieve a data reader, based on the Customers data. In
  ' an application, this data might be coming from a middle-tier
  ' business object:
  Dim reader As New DataTableReader(GetCustomers())

  ' The table has no schema. The Load method will infer the 
  ' schema from the IDataReader:
  table.Load(reader)
  PrintColumns(table)

  Console.WriteLine(" ============================= ")
  Console.WriteLine("Load a DataTable from an incompatible IDataReader:")

  ' Create a table with a single integer column. Attempt
  ' to load data from a reader with a schema that is 
  ' incompatible. Note the exception, determined
  ' by the particular incompatibility:
  table = GetIntegerTable()
  reader = New DataTableReader(GetStringTable())
  Try
    table.Load(reader)
  Catch ex As Exception
    Console.WriteLine(ex.GetType.Name & ":" & ex.Message())
  End Try

  Console.WriteLine(" ============================= ")
  Console.WriteLine( _
      "Load a DataTable with an IDataReader that has extra columns:")

  ' Note that loading a reader with extra columns adds
  ' the columns to the existing table, if possible:
  table = GetIntegerTable()
  reader = New DataTableReader(GetCustomers())
  table.Load(reader)
  PrintColumns(table)

  Console.WriteLine(" ============================= ")
  Console.WriteLine( _
      "Load a DataTable with an IDataReader that has missing columns:")

  ' Note that loading a reader with missing columns causes 
  ' the columns to be filled with null data, if possible:
  table = GetCustomers()
  reader = New DataTableReader(GetIntegerTable())
  table.Load(reader)
  PrintColumns(table)

  ' Demonstrate the various possibilites when loading data into
  ' a DataTable that already contains data.
  Console.WriteLine(" ============================= ")
  Console.WriteLine("Demonstrate data considerations:")
  Console.WriteLine("Current value, Original value, (RowState)")
  Console.WriteLine(" ============================= ")
  Console.WriteLine("Original table:")

  table = SetupModifiedRows()
  DisplayRowState(table)

  Console.WriteLine(" ============================= ")
  Console.WriteLine("Data in IDataReader to be loaded:")
  DisplayRowState(GetChangedCustomers())

  PerformDemo(LoadOption.OverwriteChanges)
  PerformDemo(LoadOption.PreserveChanges)
  PerformDemo(LoadOption.Upsert)

  Console.WriteLine("Press any key to continue.")
  Console.ReadKey()
End Sub

Private Sub DisplayRowState(ByVal table As DataTable)
  For i As Integer = 0 To table.Rows.Count - 1
    Dim current As Object = "--"
    Dim original As Object = "--"
    Dim rowState As DataRowState = table.Rows(i).RowState

    ' Attempt to retrieve the current value, which doesn't exist
    ' for deleted rows:
    If rowState <> DataRowState.Deleted Then
      current = table.Rows(i)("Name", DataRowVersion.Current)
    End If

    ' Attempt to retrieve the original value, which doesn't exist
    ' for added rows:
    If rowState <> DataRowState.Added Then
      original = table.Rows(i)("Name", DataRowVersion.Original)
    End If
    Console.WriteLine("{0}: {1}, {2} ({3})", i, current, original, rowState)
  Next
End Sub

Private Function GetChangedCustomers() As DataTable
  ' Create sample Customers table.
  Dim table As New DataTable

  ' Create two columns, ID and Name.
  Dim idColumn As DataColumn = table.Columns.Add("ID", GetType(Integer))
  table.Columns.Add("Name", GetType(String))

  ' Set the ID column as the primary key column.
  table.PrimaryKey = New DataColumn() {idColumn}

  table.Rows.Add(New Object() {0, "XXX"})
  table.Rows.Add(New Object() {1, "XXX"})
  table.Rows.Add(New Object() {2, "XXX"})
  table.Rows.Add(New Object() {3, "XXX"})
  table.Rows.Add(New Object() {4, "XXX"})
  table.AcceptChanges()
  Return table
End Function

Private Function GetCustomers() As DataTable
  ' Create sample Customers table.
  Dim table As New DataTable

  ' Create two columns, ID and Name.
  Dim idColumn As DataColumn = table.Columns.Add("ID", GetType(Integer))
  table.Columns.Add("Name", GetType(String))

  ' Set the ID column as the primary key column.
  table.PrimaryKey = New DataColumn() {idColumn}

  table.Rows.Add(New Object() {0, "Mary"})
  table.Rows.Add(New Object() {1, "Andy"})
  table.Rows.Add(New Object() {2, "Peter"})
  table.AcceptChanges()
  Return table
End Function

Private Function GetIntegerTable() As DataTable
  ' Create sample table with a single Int32 column.
  Dim table As New DataTable

  Dim idColumn As DataColumn = table.Columns.Add("ID", GetType(Integer))

  ' Set the ID column as the primary key column.
  table.PrimaryKey = New DataColumn() {idColumn}

  table.Rows.Add(New Object() {4})
  table.Rows.Add(New Object() {5})
  table.AcceptChanges()
  Return table
End Function

Private Function GetStringTable() As DataTable
  ' Create sample table with a single String column.
  Dim table As New DataTable

  Dim idColumn As DataColumn = table.Columns.Add("ID", GetType(String))

  ' Set the ID column as the primary key column.
  table.PrimaryKey = New DataColumn() {idColumn}

  table.Rows.Add(New Object() {"Mary"})
  table.Rows.Add(New Object() {"Andy"})
  table.Rows.Add(New Object() {"Peter"})
  table.AcceptChanges()
  Return table
End Function

Private Sub PerformDemo(ByVal optionForLoad As LoadOption)

  ' Load data into a DataTable, retrieve a DataTableReader containing
  ' different data, and call the Load method. Depending on the
  ' LoadOption value passed as a parameter, this procedure displays
  ' different results in the DataTable.
  Console.WriteLine(" ============================= ")
  Console.WriteLine("table.Load(reader, {0})", optionForLoad)
  Console.WriteLine(" ============================= ")

  Dim table As DataTable = SetupModifiedRows()
  Dim reader As New DataTableReader(GetChangedCustomers())
  AddHandler table.RowChanging, New _
      DataRowChangeEventHandler(AddressOf HandleRowChanging)

  table.Load(reader, optionForLoad)
  Console.WriteLine()
  DisplayRowState(table)
End Sub

Private Sub PrintColumns( _
   ByVal table As DataTable)

  ' Loop through all the rows in the DataTableReader.
  For Each row As DataRow In table.Rows
    For Each col As DataColumn In table.Columns
      Console.Write(row(col).ToString() & " ")
    Next
    Console.WriteLine()
  Next
End Sub

Private Function SetupModifiedRows() As DataTable
  ' Fill a DataTable with customer info, and 
  ' then modify, delete, and add rows.

  Dim table As DataTable = GetCustomers()
  ' Row 0 is unmodified.
  ' Row 1 is modified.
  ' Row 2 is deleted.
  ' Row 3 is added.
  table.Rows(1)("Name") = "Sydney"
  table.Rows(2).Delete()
  Dim row As DataRow = table.NewRow
  row("ID") = 3
  row("Name") = "Melony"
  table.Rows.Add(row)

  ' Note that the code doesn't call
  ' table.AcceptChanges()
  Return table
End Function

Private Sub HandleRowChanging(ByVal sender As Object, _
  ByVal e As System.Data.DataRowChangeEventArgs)
  Console.WriteLine( _
      "RowChanging event: ID = {0}, action = {1}", e.Row("ID"), _
      e.Action)
End Sub

備註

方法Load可以用於數個常見的案例,全都是以從指定的資料來源取得資料,並將它加入至目前的資料容器(在此案例中DataTable為)。The Load method can be used in several common scenarios, all centered around getting data from a specified data source and adding it to the current data container (in this case, a DataTable). 這些案例描述的DataTable標準使用方式,並說明其更新和合併行為。These scenarios describe standard usage for a DataTable, describing its update and merge behavior.

具有DataTable單一主要資料來源的同步處理或更新。A DataTable synchronizes or updates with a single primary data source. DataTable追蹤變更,允許與主要資料來源進行同步處理。The DataTable tracks changes, allowing synchronization with the primary data source. 此外,可以接受DataTable一或多個次要資料來源中的增量資料。In addition, a DataTable can accept incremental data from one or more secondary data sources. DataTable不負責追蹤變更,以便允許與次要資料來源進行同步處理。The DataTable isn't responsible for tracking changes in order to allow synchronization with the secondary data source.

假設有這兩個假設性資料來源,使用者可能需要下列其中一種行為:Given these two hypothetical data sources, a user is likely to require one of the following behaviors:

  • DataTable主要資料來源初始化。Initialize DataTable from a primary data source. 在此案例中,使用者想要使用來自主要DataTable資料來源的值來初始化空的。In this scenario, the user wants to initialize an empty DataTable with values from the primary data source. 之後,使用者打算將變更傳播回主要資料來源。Later the user intends to propagate changes back to the primary data source.

  • 保留變更,並從主要資料來源重新同步處理。Preserve changes and re-synchronize from the primary data source. 在此案例中,使用者想要取得前DataTable一個案例的填滿,並與主要資料來源執行累加式同步處理,保留中所做DataTable的修改。In this scenario, the user wants to take the DataTable filled in the previous scenario and perform an incremental synchronization with the primary data source, preserving modifications made in the DataTable.

  • 來自次要資料來源的累加式資料摘要。Incremental data feed from secondary data sources. 在此案例中,使用者想要合併一或多個次要資料來源的變更,並將這些變更傳播回主要資料來源。In this scenario, the user wants to merge changes from one or more secondary data sources, and propagate those changes back to the primary data source.

Load方法可實現所有這些案例。The Load method makes all these scenarios possible. 除了這個方法的其中一個多載,還可讓您指定載入選項參數,指出中的資料列與DataTable載入的資料列結合的方式。All but one of the overloads for this method allows you to specify a load option parameter, indicating how rows already in a DataTable combine with rows being loaded. (不允許您指定行為的多載會使用預設載入選項)。下表描述LoadOption列舉所提供的三個載入選項。(The overload that doesn't allow you to specify the behavior uses the default load option.) The following table describes the three load options provided by the LoadOption enumeration. 在每個案例中,此描述會指出傳入資料中,資料列的主鍵符合現有資料列的主鍵時的行為。In each case, the description indicates the behavior when the primary key of a row in the incoming data matches the primary key of an existing row.

載入選項Load Option 說明Description
PreserveChanges (預設)PreserveChanges (default) 使用內送資料列的值,更新資料列的原始版本。Updates the original version of the row with the value of the incoming row.
OverwriteChanges 使用傳入資料列的值,更新資料列的目前和原始版本。Updates the current and original versions of the row with the value of the incoming row.
Upsert 使用傳入資料列的值,更新資料列的目前版本。Updates the current version of the row with the value of the incoming row.

一般來說, PreserveChangesOverwriteChanges選項適用于使用者需要與主要資料來源同步處理及其變更的DataSet案例。In general, the PreserveChanges and OverwriteChanges options are intended for scenarios in which the user needs to synchronize the DataSet and its changes with the primary data source. Upsert選項可協助匯總一或多個次要資料來源中的變更。The Upsert option facilitates aggregating changes from one or more secondary data sources.

Load(IDataReader) Load(IDataReader) Load(IDataReader) Load(IDataReader)

使用所提供的 DataTable,用資料來源的值填滿 IDataReaderFills a DataTable with values from a data source using the supplied IDataReader. 如果 DataTable 已經包含資料列,從資料來源傳入的資料會與現有的資料列合併。If the DataTable already contains rows, the incoming data from the data source is merged with the existing rows.

public:
 void Load(System::Data::IDataReader ^ reader);
public void Load (System.Data.IDataReader reader);
member this.Load : System.Data.IDataReader -> unit
Public Sub Load (reader As IDataReader)

參數

reader
IDataReader IDataReader IDataReader IDataReader

IDataReader,提供結果集。An IDataReader that provides a result set.

範例

下列範例示範呼叫Load方法時所牽涉到的幾個問題。The following example demonstrates several of the issues involved with calling the Load method. 首先,此範例著重于架構問題,包括從載入IDataReader的中推斷架構,然後處理不相容的架構,以及遺漏或其他資料行的架構。First, the example focuses on schema issues, including inferring a schema from the loaded IDataReader, and then handling incompatible schemas, and schemas with missing or additional columns. 然後,此範例會Load呼叫方法,並在載入作業之前和之後顯示資料。The example then calls the Load method, displaying the data both before and after the load operation.

static void Main()
{
    // This example examines a number of scenarios involving the 
    // DataTable.Load method.
    Console.WriteLine("Load a DataTable and infer its schema:");

    // The table has no schema. The Load method will infer the 
    // schema from the IDataReader:
    DataTable table = new DataTable();

    // Retrieve a data reader, based on the Customers data. In
    // an application, this data might be coming from a middle-tier
    // business object:
    DataTableReader reader = new DataTableReader(GetCustomers());

    table.Load(reader);
    PrintColumns(table);

    Console.WriteLine(" ============================= ");
    Console.WriteLine(
        "Load a DataTable from an incompatible IDataReader:");

    // Create a table with a single integer column. Attempt
    // to load data from a reader with a schema that is 
    // incompatible. Note the exception, determined
    // by the particular incompatibility:
    table = GetIntegerTable();
    reader = new DataTableReader(GetStringTable());
    try 
    {
        table.Load(reader);
    } 
    catch (Exception ex) 
    { 
        Console.WriteLine(ex.GetType().Name + ":" + ex.Message);
    }

    Console.WriteLine(" ============================= ");
    Console.WriteLine(
        "Load a DataTable with an IDataReader that has extra columns:");

    // Note that loading a reader with extra columns adds
    // the columns to the existing table, if possible:
    table = GetIntegerTable();
    reader = new DataTableReader(GetCustomers());
    table.Load(reader);
    PrintColumns(table);

    Console.WriteLine(" ============================= ");
    Console.WriteLine(
        "Load a DataTable with an IDataReader that has missing columns:");

    // Note that loading a reader with missing columns causes 
    // the columns to be filled with null data, if possible:
    table = GetCustomers();
    reader = new DataTableReader(GetIntegerTable());
    table.Load(reader);
    PrintColumns(table);

    // Demonstrate the various possibilites when loading data 
    // into a DataTable that already contains data.
    Console.WriteLine(" ============================= ");
    Console.WriteLine("Demonstrate data considerations:");
    Console.WriteLine("Current value, Original value, (RowState)");
    Console.WriteLine(" ============================= ");
    Console.WriteLine("Original table:");

    table = SetupModifiedRows();
    DisplayRowState(table);

    Console.WriteLine(" ============================= ");
    Console.WriteLine("Data in IDataReader to be loaded:");
    DisplayRowState(GetChangedCustomers());

    // Load data into a DataTable, retrieve a DataTableReader 
    // containing different data, and call the Load method. 
    Console.WriteLine(" ============================= ");
    Console.WriteLine("table.Load(reader)");
    Console.WriteLine(" ============================= ");

    table = SetupModifiedRows();
    reader = new DataTableReader(GetChangedCustomers());
    table.Load(reader);
    DisplayRowState(table);

    Console.WriteLine("Press any key to continue.");
    Console.ReadKey();
}

private static void DisplayRowState(DataTable table)
{
    for (int i = 0; i <= table.Rows.Count - 1; i++)
    {
        object current = "--";
        object original = "--";
        DataRowState rowState = table.Rows[i].RowState;

        // Attempt to retrieve the current value, which doesn't exist
        // for deleted rows:
        if (rowState != DataRowState.Deleted)
        {
            current = table.Rows[i]["Name", DataRowVersion.Current];
        }

        // Attempt to retrieve the original value, which doesn't exist
        // for added rows:
        if (rowState != DataRowState.Added)
        {
            original = table.Rows[i]["Name", DataRowVersion.Original];
        }
        Console.WriteLine("{0}: {1}, {2} ({3})", i, 
            current, original, rowState);
    }
}

private static DataTable GetChangedCustomers()
{
    // Create sample Customers table.
    DataTable table = new DataTable();

    // Create two columns, ID and Name.
    DataColumn idColumn = table.Columns.Add("ID", 
        typeof(int));
    table.Columns.Add("Name", typeof(string));

    // Set the ID column as the primary key column.
    table.PrimaryKey = new DataColumn[] { idColumn };

    table.Rows.Add(new object[] { 1, "XXX" });
    table.Rows.Add(new object[] { 2, "XXX" });
    table.Rows.Add(new object[] { 3, "XXX" });
    table.Rows.Add(new object[] { 4, "XXX" });
    table.Rows.Add(new object[] { 5, "XXX" });
    table.Rows.Add(new object[] { 6, "XXX" });
    table.AcceptChanges();
    return table;
}

private static DataTable GetCustomers()
{
    // Create sample Customers table, in order
    // to demonstrate the behavior of the DataTableReader.
    DataTable table = new DataTable();

    // Create two columns, ID and Name.
    DataColumn idColumn = table.Columns.Add("ID", 
        typeof(int));
    table.Columns.Add("Name", typeof(string));

    // Set the ID column as the primary key column.
    table.PrimaryKey = new DataColumn[] { idColumn };

    table.Rows.Add(new object[] { 1, "Mary" });
    table.Rows.Add(new object[] { 2, "Andy" });
    table.Rows.Add(new object[] { 3, "Peter" });
    table.Rows.Add(new object[] { 4, "Russ" });
    table.AcceptChanges();
    return table;
}

private static DataTable GetIntegerTable()
{
    // Create sample Customers table, in order
    // to demonstrate the behavior of the DataTableReader.
    DataTable table = new DataTable();

    // Create two columns, ID and Name.
    DataColumn idColumn = table.Columns.Add("ID", 
        typeof(int));

    // Set the ID column as the primary key column.
    table.PrimaryKey = new DataColumn[] { idColumn };

    table.Rows.Add(new object[] { 5 });
    table.Rows.Add(new object[] { 6 });
    table.Rows.Add(new object[] { 7 });
    table.Rows.Add(new object[] { 8 });
    table.AcceptChanges();
    return table;
}

private static DataTable GetStringTable()
{
    // Create sample Customers table, in order
    // to demonstrate the behavior of the DataTableReader.
    DataTable table = new DataTable();

    // Create two columns, ID and Name.
    DataColumn idColumn = table.Columns.Add("ID", 
        typeof(string));

    // Set the ID column as the primary key column.
    table.PrimaryKey = new DataColumn[] { idColumn };

    table.Rows.Add(new object[] { "Mary" });
    table.Rows.Add(new object[] { "Andy" });
    table.Rows.Add(new object[] { "Peter" });
    table.Rows.Add(new object[] { "Russ" });
    table.AcceptChanges();
    return table;
}

private static void PrintColumns(DataTable table)
{
    // Loop through all the rows in the DataTableReader
    foreach (DataRow row in table.Rows)
    {
        for (int i = 0; i < table.Columns.Count; i++)
        {
            Console.Write(row[i] + " ");
        }
        Console.WriteLine();
    }
}

private static DataTable SetupModifiedRows()
{
    // Fill a DataTable with customer info, and 
    // then modify, delete, and add rows.

    DataTable table = GetCustomers();
    // Row 0 is unmodified.
    // Row 1 is modified.
    // Row 2 is deleted.
    // Row 5 is added.
    table.Rows[1]["Name"] = "Sydney";
    table.Rows[2].Delete();
    DataRow row = table.NewRow();
    row["ID"] = 5;
    row["Name"] = "Melony";
    table.Rows.Add(row);

    // Note that the code doesn't call
    // table.AcceptChanges()
    return table;
}
Sub Main()
  ' This example examines a number of scenarios involving the 
  ' DataTable.Load method.
  Console.WriteLine("Load a DataTable and infer its schema:")

  ' The table has no schema. The Load method will infer the 
  ' schema from the IDataReader:
  Dim table As New DataTable()

  ' Retrieve a data reader, based on the Customers data. In
  ' an application, this data might be coming from a middle-tier
  ' business object:
  Dim reader As New DataTableReader(GetCustomers())

  table.Load(reader)
  PrintColumns(table)

  Console.WriteLine(" ============================= ")
  Console.WriteLine( _
      "Load a DataTable from an incompatible IDataReader:")

  ' Create a table with a single integer column. Attempt
  ' to load data from a reader with a schema that is 
  ' incompatible. Note the exception, determined
  ' by the particular incompatibility:
  table = GetIntegerTable()
  reader = New DataTableReader(GetStringTable())
  Try
    table.Load(reader)
  Catch ex As Exception
    Console.WriteLine(ex.GetType.Name & ":" & ex.Message())
  End Try

  Console.WriteLine(" ============================= ")
  Console.WriteLine( _
      "Load a DataTable with an IDataReader that has extra columns:")

  ' Note that loading a reader with extra columns adds
  ' the columns to the existing table, if possible:
  table = GetIntegerTable()
  reader = New DataTableReader(GetCustomers())
  table.Load(reader)
  PrintColumns(table)

  Console.WriteLine(" ============================= ")
      Console.WriteLine( _
          "Load a DataTable with an IDataReader that has missing columns:")

  ' Note that loading a reader with missing columns causes 
  ' the columns to be filled with null data, if possible:
  table = GetCustomers()
  reader = New DataTableReader(GetIntegerTable())
  table.Load(reader)
  PrintColumns(table)

  ' Demonstrate the various possibilites when loading data into
  ' a DataTable that already contains data.
  Console.WriteLine(" ============================= ")
  Console.WriteLine("Demonstrate data considerations:")
  Console.WriteLine("Current value, Original value, (RowState)")
  Console.WriteLine(" ============================= ")
  Console.WriteLine("Original table:")

  table = SetupModifiedRows()
  DisplayRowState(table)

  Console.WriteLine(" ============================= ")
  Console.WriteLine("Data in IDataReader to be loaded:")
  DisplayRowState(GetChangedCustomers())

  ' Load data into a DataTable, retrieve a DataTableReader 
  ' containing different data, and call the Load method. 
  Console.WriteLine(" ============================= ")
  Console.WriteLine("table.Load(reader)")
  Console.WriteLine(" ============================= ")

  table = SetupModifiedRows()
  reader = New DataTableReader(GetChangedCustomers())
  table.Load(reader)
  DisplayRowState(table)

  Console.WriteLine("Press any key to continue.")
  Console.ReadKey()
End Sub

Private Sub DisplayRowState(ByVal table As DataTable)
  For i As Integer = 0 To table.Rows.Count - 1
    Dim current As Object = "--"
    Dim original As Object = "--"
    Dim rowState As DataRowState = table.Rows(i).RowState

    ' Attempt to retrieve the current value, which doesn't exist
    ' for deleted rows:
    If rowState <> DataRowState.Deleted Then
      current = table.Rows(i)("Name", DataRowVersion.Current)
    End If

    ' Attempt to retrieve the original value, which doesn't exist
    ' for added rows:
    If rowState <> DataRowState.Added Then
      original = table.Rows(i)("Name", DataRowVersion.Original)
    End If
    Console.WriteLine("{0}: {1}, {2} ({3})", i, _
      current, original, rowState)
  Next
End Sub

Private Function GetChangedCustomers() As DataTable
  ' Create sample Customers table.
  Dim table As New DataTable

  ' Create two columns, ID and Name.
  Dim idColumn As DataColumn = table.Columns.Add("ID", _
      GetType(Integer))
  table.Columns.Add("Name", GetType(String))

  ' Set the ID column as the primary key column.
  table.PrimaryKey = New DataColumn() {idColumn}

  table.Rows.Add(New Object() {1, "XXX"})
  table.Rows.Add(New Object() {2, "XXX"})
  table.Rows.Add(New Object() {3, "XXX"})
  table.Rows.Add(New Object() {4, "XXX"})
  table.Rows.Add(New Object() {5, "XXX"})
  table.Rows.Add(New Object() {6, "XXX"})
  table.AcceptChanges()
  Return table
End Function

Private Function GetCustomers() As DataTable
  ' Create sample Customers table.
  Dim table As New DataTable

  ' Create two columns, ID and Name.
  Dim idColumn As DataColumn = table.Columns.Add("ID", _
      GetType(Integer))
  table.Columns.Add("Name", GetType(String))

  ' Set the ID column as the primary key column.
  table.PrimaryKey = New DataColumn() {idColumn}

  table.Rows.Add(New Object() {1, "Mary"})
  table.Rows.Add(New Object() {2, "Andy"})
  table.Rows.Add(New Object() {3, "Peter"})
  table.Rows.Add(New Object() {4, "Russ"})
  table.AcceptChanges()
  Return table
End Function

Private Function GetIntegerTable() As DataTable
  ' Create sample table with a single Int32 column.
  Dim table As New DataTable

  Dim idColumn As DataColumn = table.Columns.Add("ID", _
      GetType(Integer))

  ' Set the ID column as the primary key column.
  table.PrimaryKey = New DataColumn() {idColumn}

  table.Rows.Add(New Object() {5})
  table.Rows.Add(New Object() {6})
  table.Rows.Add(New Object() {7})
  table.Rows.Add(New Object() {8})
  table.AcceptChanges()
  Return table
End Function

Private Function GetStringTable() As DataTable
  ' Create sample table with a single String column.
  Dim table As New DataTable

  Dim idColumn As DataColumn = table.Columns.Add("ID", _
      GetType(String))

  ' Set the ID column as the primary key column.
  table.PrimaryKey = New DataColumn() {idColumn}

  table.Rows.Add(New Object() {"Mary"})
  table.Rows.Add(New Object() {"Andy"})
  table.Rows.Add(New Object() {"Peter"})
  table.Rows.Add(New Object() {"Russ"})
  table.AcceptChanges()
  Return table
End Function

Private Sub PrintColumns( _
   ByVal table As DataTable)

  ' Loop through all the rows in the DataTableReader.
  For Each row As DataRow In table.Rows
    For Each col As DataColumn In table.Columns
      Console.Write(row(col).ToString() & " ")
    Next
    Console.WriteLine()
  Next
End Sub

Private Function SetupModifiedRows() As DataTable
  ' Fill a DataTable with customer info, and 
  ' then modify, delete, and add rows.

  Dim table As DataTable = GetCustomers()
  ' Row 0 is unmodified.
  ' Row 1 is modified.
  ' Row 2 is deleted.
  ' Row 5 is added.
  table.Rows(1)("Name") = "Sydney"
  table.Rows(2).Delete()
  Dim row As DataRow = table.NewRow
  row("ID") = 5
  row("Name") = "Melony"
  table.Rows.Add(row)

  ' Note that the code doesn't call
  ' table.AcceptChanges()
  Return table
End Function

備註

方法會取用所載入IDataReader的第一個結果集,而且在成功完成後,會將讀取器的位置設定為下一個結果集(如果有的話)。 LoadThe Load method consumes the first result set from the loaded IDataReader, and after successful completion, sets the reader's position to the next result set, if any. 轉換資料時, Load方法會使用與DbDataAdapter.Fill方法相同的轉換規則。When converting data, the Load method uses the same conversion rules as the DbDataAdapter.Fill method.

從實例載入資料時,此Load方法必須考慮三個特定的問題:架構、資料和事件作業。 IDataReaderThe Load method must take into account three specific issues when loading the data from an IDataReader instance: schema, data, and event operations. 使用此架構時,此Load方法可能會遇到條件,如下表所述。When working with the schema, the Load method may encounter conditions as described in the following table. 架構作業會針對所有匯入的結果集進行,即使不包含任何資料。The schema operations take place for all imported result sets, even those containing no data.

條件Condition 行為Behavior
DataTable沒有架構。The DataTable has no schema. 方法會根據匯入IDataReader的結果集來推斷架構。 LoadThe Load method infers the schema based on the result set from the imported IDataReader.
DataTable具有架構,但它與載入的架構不相容。The DataTable has a schema, but it is incompatible with the loaded schema. Load方法會擲回例外狀況,對應于嘗試將資料載入不相容的架構時所發生的特定錯誤。The Load method throws an exception corresponding to the particular error that occurs when attempting to load data into the incompatible schema.
架構相容,但載入的結果集架構包含不存在於中DataTable的資料行。The schemas are compatible, but the loaded result set schema contains columns that do not exist in the DataTable. 方法會將額外的資料行DataTable新增至的架構。 LoadThe Load method adds the extra columns to DataTable's schema. 如果DataTable和載入的結果集中的對應資料行與值不相容,則方法會擲回例外狀況。The method throws an exception if corresponding columns in the DataTable and the loaded result set are not value compatible. 此方法也會從所有加入之資料行的結果集中,取得條件約束資訊。The method also retrieves constraint information from the result set for all added columns. 除了 Primary Key 條件約束的案例以外,只有當目前DataTable的不包含載入作業開始時的任何資料行時,才會使用此條件約束資訊。Except for the case of Primary Key constraint, this constraint information is used only if the current DataTable does not contain any columns at the start of the load operation.
架構相容,但載入的結果集架構所包含的DataTable資料行比更少。The schemas are compatible, but the loaded result set schema contains fewer columns than does the DataTable. 如果遺漏的資料行已定義預設值,或資料行的資料類型可為 null Load ,則此方法會允許加入資料列,並以null遺漏資料行的預設值或值取代。If a missing column has a default value defined or the column's data type is nullable, the Load method allows the rows to be added, substituting the default or null value for the missing column. 如果沒有預設值或null可以使用, Load則方法會擲回例外狀況。If no default value or null can be used, then the Load method throws an exception. 如果未提供任何特定的預設值,此Load方法會null使用值做為隱含的預設值。If no specific default value has been supplied, the Load method uses the null value as the implied default value.

在考慮資料作業方面的Load方法行為之前,請考慮在DataTable中的每個資料列都會維護目前的值和每個資料行的原始值。Before considering the behavior of the Load method in terms of data operations, consider that each row within a DataTable maintains both the current value and the original value for each column. 這些值可能相等,或者,如果資料列中的資料在填滿DataTable之後已經變更,可能會有所不同。These values may be equivalent, or may be different if the data in the row has been changed since filling the DataTable. 如需詳細資訊,請參閱資料列狀態和資料列版本For more information, see Row States and Row Versions.

這個版本的Load方法會嘗試保留每個資料列中的目前值,讓原始值保持不變。This version of the Load method attempts to preserve the current values in each row, leaving the original value intact. (如果您想要更精確地控制傳入資料的行為, DataTable.Load請參閱)。如果現有的資料列和內送資料列包含對應的主鍵值,則會使用其目前的資料列狀態值來處理資料列,否則會將它視為新的資料列。(If you want finer control over the behavior of incoming data, see DataTable.Load.) If the existing row and the incoming row contain corresponding primary key values, the row is processed using its current row state value, otherwise it's treated as a new row.

就事件作業而言, RowChanging事件會在每個資料列變更之前發生, RowChanged而事件會在每個資料列變更後發生。In terms of event operations, the RowChanging event occurs before each row is changed, and the RowChanged event occurs after each row has been changed. 在每個案例中Action ,傳遞至DataRowChangeEventArgs事件處理常式之實例的屬性,包含與事件相關聯之特定動作的資訊。In each case, the Action property of the DataRowChangeEventArgs instance passed to the event handler contains information about the particular action associated with the event. 此動作值取決於載入作業之前的資料列狀態。This action value depends on the state of the row before the load operation. 在每個案例中,都會發生這兩個事件,每個都會有相同的動作。In each case, both events occur, and the action is the same for each. 視目前的資料列狀態而定,動作可能會套用至每個資料列的目前或原始版本,或兩者。The action may be applied to either the current or original version of each row, or both, depending on the current row state.

下表顯示Load方法的行為。The following table displays behavior for the Load method. 最後一個資料列(標示為「(不存在)」)描述不符合任何現有資料列之傳入資料列的行為。The final row (labeled "(Not present)") describes the behavior for incoming rows that don't match any existing row. 下表中的每個資料格都會描述資料列內欄位的目前和原始值,以及DataRowState Load方法完成後,值的。Each cell in this table describes the current and original value for a field within a row, along with the DataRowState for the value after the Load method has completed. 在此情況下,方法不允許您指定載入選項,並使用預設值PreserveChangesIn this case, the method doesn't allow you to indicate the load option, and uses the default, PreserveChanges.

現有的 DataRowStateExisting DataRowState [方法Load ] 和 [事件動作] 後面的值Values after Load method, and event action
AddedAdded 目前 = <現有 >Current = <Existing>

原始 = <傳入 >Original = <Incoming>

狀態 = <已修改 >State = <Modified>

RowAction = ChangeOriginalRowAction = ChangeOriginal
修改時間Modified 目前 = <現有 >Current = <Existing>

原始 = <傳入 >Original = <Incoming>

狀態 = <已修改 >State = <Modified>

RowAction = ChangeOriginalRowAction = ChangeOriginal
DeletedDeleted 目前 = <無法使用 >Current = <Not available>

原始 = <傳入 >Original = <Incoming>

狀態 = <已刪除 >State = <Deleted>

RowAction = ChangeOriginalRowAction = ChangeOriginal
UnchangedUnchanged 目前 = <傳入 >Current = <Incoming>

原始 = <傳入 >Original = <Incoming>

狀態 = <未變更的 >State = <Unchanged>

RowAction = ChangeCurrentAndOriginalRowAction = ChangeCurrentAndOriginal
(不存在)(Not present) 目前 = <傳入 >Current = <Incoming>

原始 = <傳入 >Original = <Incoming>

狀態 = <未變更的 >State = <Unchanged>

RowAction = ChangeCurrentAndOriginalRowAction = ChangeCurrentAndOriginal

DataColumn的值可透過使用屬性ReadOnly (例如和AutoIncrement)來加以限制。Values in a DataColumn can be constrained through use of properties such as ReadOnly and AutoIncrement. Load方法會以與資料行屬性所定義的行為一致的方式來處理這類資料行。The Load method handles such columns in a manner that is consistent with the behavior defined by the column's properties. DataColumn的唯讀條件約束僅適用于記憶體中發生的變更。The read only constraint on a DataColumn is applicable only for changes that occur in memory. 如有需要,方法的會覆寫唯讀資料行值。LoadThe Load method's overwrites the read-only column values, if needed.

若要判斷要用來比較目前資料列與內送資料列的主要索引鍵欄位版本, Load方法會在資料列中使用原始版本的主要金鑰值(如果有的話)。To determine which version of the primary key field to use for comparing the current row with an incoming row, the Load method uses the original version of the primary key value within a row, if it exists. 否則, Load方法會使用主要金鑰欄位的目前版本。Otherwise, the Load method uses the current version of the primary key field.

另請參閱

Load(IDataReader, LoadOption) Load(IDataReader, LoadOption) Load(IDataReader, LoadOption)

使用所提供的 DataTable,用資料來源的值填滿 IDataReaderFills a DataTable with values from a data source using the supplied IDataReader. 如果 DataTable 已經包含資料列,從資料來源傳入的資料會根據 loadOption 參數的值,與現有的資料列合併。If the DataTable already contains rows, the incoming data from the data source is merged with the existing rows according to the value of the loadOption parameter.

public:
 void Load(System::Data::IDataReader ^ reader, System::Data::LoadOption loadOption);
public void Load (System.Data.IDataReader reader, System.Data.LoadOption loadOption);
member this.Load : System.Data.IDataReader * System.Data.LoadOption -> unit

參數

reader
IDataReader IDataReader IDataReader IDataReader

IDataReader,提供一個或多個結果集。An IDataReader that provides one or more result sets.

loadOption
LoadOption LoadOption LoadOption LoadOption

來自 LoadOption 列舉的值,指出已經在 DataTable 中的資料列如何與共用相同主索引鍵的傳入資料列結合。A value from the LoadOption enumeration that indicates how rows already in the DataTable are combined with incoming rows that share the same primary key.

範例

下列範例示範呼叫Load方法時所牽涉到的幾個問題。The following example demonstrates several of the issues involved with calling the Load method. 首先,此範例著重于架構問題,包括從載入IDataReader的中推斷架構,然後處理不相容的架構,以及遺漏或其他資料行的架構。First, the example focuses on schema issues, including inferring a schema from the loaded IDataReader, and then handling incompatible schemas, and schemas with missing or additional columns. 然後,此範例會著重于資料問題,包括處理各種載入選項。The example then focuses on data issues, including handling the various loading options.

static void Main()
{
    // This example examines a number of scenarios involving the 
    // DataTable.Load method.
    Console.WriteLine("Load a DataTable and infer its schema:");

    // The table has no schema. The Load method will infer the 
    // schema from the IDataReader:
    DataTable table = new DataTable();

    // Retrieve a data reader, based on the Customers data. In
    // an application, this data might be coming from a middle-tier
    // business object:
    DataTableReader reader = new DataTableReader(GetCustomers());

    table.Load(reader);
    PrintColumns(table);

    Console.WriteLine(" ============================= ");
    Console.WriteLine(
        "Load a DataTable from an incompatible IDataReader:");

    // Create a table with a single integer column. Attempt
    // to load data from a reader with a schema that is 
    // incompatible. Note the exception, determined
    // by the particular incompatibility:
    table = GetIntegerTable();
    reader = new DataTableReader(GetStringTable());
    try
    {
        table.Load(reader);
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.GetType().Name + ":" + ex.Message);
    }

    Console.WriteLine(" ============================= ");
    Console.WriteLine(
        "Load a DataTable with an IDataReader that has extra columns:");

    // Note that loading a reader with extra columns adds
    // the columns to the existing table, if possible:
    table = GetIntegerTable();
    reader = new DataTableReader(GetCustomers());
    table.Load(reader);
    PrintColumns(table);

    Console.WriteLine(" ============================= ");
    Console.WriteLine(
        "Load a DataTable with an IDataReader that has missing columns:");

    // Note that loading a reader with missing columns causes 
    // the columns to be filled with null data, if possible:
    table = GetCustomers();
    reader = new DataTableReader(GetIntegerTable());
    table.Load(reader);
    PrintColumns(table);

    // Demonstrate the various possibilites when loading data into
    // a DataTable that already contains data.
    Console.WriteLine(" ============================= ");
    Console.WriteLine("Demonstrate data considerations:");
    Console.WriteLine("Current value, Original value, (RowState)");
    Console.WriteLine(" ============================= ");
    Console.WriteLine("Original table:");

    table = SetupModifiedRows();
    DisplayRowState(table);

    Console.WriteLine(" ============================= ");
    Console.WriteLine("Data in IDataReader to be loaded:");
    DisplayRowState(GetChangedCustomers());

    PerformDemo(LoadOption.OverwriteChanges);
    PerformDemo(LoadOption.PreserveChanges);
    PerformDemo(LoadOption.Upsert);

    Console.WriteLine("Press any key to continue.");
    Console.ReadKey();
}

private static void DisplayRowState(DataTable table)
{
    for (int i = 0; i <= table.Rows.Count - 1; i++)
    {
        object current = "--";
        object original = "--";
        DataRowState rowState = table.Rows[i].RowState;

        // Attempt to retrieve the current value, which doesn't exist
        // for deleted rows:
        if (rowState != DataRowState.Deleted)
        {
            current = table.Rows[i]["Name", DataRowVersion.Current];
        }

        // Attempt to retrieve the original value, which doesn't exist
        // for added rows:
        if (rowState != DataRowState.Added)
        {
            original = table.Rows[i]["Name", DataRowVersion.Original];
        }
        Console.WriteLine("{0}: {1}, {2} ({3})", i, 
            current, original, rowState);
    }
}

private static DataTable GetChangedCustomers()
{
    // Create sample Customers table.
    DataTable table = new DataTable();

    // Create two columns, ID and Name.
    DataColumn idColumn = table.Columns.Add("ID", typeof(int));
    table.Columns.Add("Name", typeof(string));

    // Set the ID column as the primary key column.
    table.PrimaryKey = new DataColumn[] { idColumn };

    table.Rows.Add(new object[] { 0, "XXX" });
    table.Rows.Add(new object[] { 1, "XXX" });
    table.Rows.Add(new object[] { 2, "XXX" });
    table.Rows.Add(new object[] { 3, "XXX" });
    table.Rows.Add(new object[] { 4, "XXX" });
    table.AcceptChanges();
    return table;
}

private static DataTable GetCustomers()
{
    // Create sample Customers table, in order
    // to demonstrate the behavior of the DataTableReader.
    DataTable table = new DataTable();

    // Create two columns, ID and Name.
    DataColumn idColumn = table.Columns.Add("ID", typeof(int));
    table.Columns.Add("Name", typeof(string));

    // Set the ID column as the primary key column.
    table.PrimaryKey = new DataColumn[] { idColumn };

    table.Rows.Add(new object[] { 0, "Mary" });
    table.Rows.Add(new object[] { 1, "Andy" });
    table.Rows.Add(new object[] { 2, "Peter" });
    table.AcceptChanges();
    return table;
}

private static DataTable GetIntegerTable()
{
    // Create sample Customers table, in order
    // to demonstrate the behavior of the DataTableReader.
    DataTable table = new DataTable();

    // Create two columns, ID and Name.
    DataColumn idColumn = table.Columns.Add("ID", typeof(int));

    // Set the ID column as the primary key column.
    table.PrimaryKey = new DataColumn[] { idColumn };

    table.Rows.Add(new object[] { 4 });
    table.Rows.Add(new object[] { 5 });
    table.AcceptChanges();
    return table;
}

private static DataTable GetStringTable()
{
    // Create sample Customers table, in order
    // to demonstrate the behavior of the DataTableReader.
    DataTable table = new DataTable();

    // Create two columns, ID and Name.
    DataColumn idColumn = table.Columns.Add("ID", typeof(string));

    // Set the ID column as the primary key column.
    table.PrimaryKey = new DataColumn[] { idColumn };

    table.Rows.Add(new object[] { "Mary" });
    table.Rows.Add(new object[] { "Andy" });
    table.Rows.Add(new object[] { "Peter" });
    table.AcceptChanges();
    return table;
}

private static void PerformDemo(LoadOption optionForLoad)
{

    // Load data into a DataTable, retrieve a DataTableReader containing
    // different data, and call the Load method. Depending on the
    // LoadOption value passed as a parameter, this procedure displays
    // different results in the DataTable.
    Console.WriteLine(" ============================= ");
    Console.WriteLine("table.Load(reader, {0})", optionForLoad);
    Console.WriteLine(" ============================= ");

    DataTable table = SetupModifiedRows();
    DataTableReader reader = new DataTableReader(GetChangedCustomers());
    table.RowChanging +=new DataRowChangeEventHandler(HandleRowChanging);

    table.Load(reader, optionForLoad);
    Console.WriteLine();
    DisplayRowState(table);
}

private static void PrintColumns(DataTable table)
{
    // Loop through all the rows in the DataTableReader
    foreach (DataRow row in table.Rows)
    {
        for (int i = 0; i < table.Columns.Count; i++)
        {
            Console.Write(row[i] + " ");
        }
        Console.WriteLine();
    }
}

private static DataTable SetupModifiedRows()
{
    // Fill a DataTable with customer info, and 
    // then modify, delete, and add rows.

    DataTable table = GetCustomers();
    // Row 0 is unmodified.
    // Row 1 is modified.
    // Row 2 is deleted.
    // Row 3 is added.
    table.Rows[1]["Name"] = "Sydney";
    table.Rows[2].Delete();
    DataRow row = table.NewRow();
    row["ID"] = 3;
    row["Name"] = "Melony";
    table.Rows.Add(row);

    // Note that the code doesn't call
    // table.AcceptChanges()
    return table;
}

static void HandleRowChanging(object sender, DataRowChangeEventArgs e)
{
    Console.WriteLine(
        "RowChanging event: ID = {0}, action = {1}", e.Row["ID"], e.Action);
}
Sub Main()
  Dim table As New DataTable()

  ' This example examines a number of scenarios involving the
  '  DataTable.Load method.
  Console.WriteLine("Load a DataTable and infer its schema:")

  ' Retrieve a data reader, based on the Customers data. In
  ' an application, this data might be coming from a middle-tier
  ' business object:
  Dim reader As New DataTableReader(GetCustomers())

  ' The table has no schema. The Load method will infer the 
  ' schema from the IDataReader:
  table.Load(reader)
  PrintColumns(table)

  Console.WriteLine(" ============================= ")
  Console.WriteLine( _
      "Load a DataTable from an incompatible IDataReader:")

  ' Create a table with a single integer column. Attempt
  ' to load data from a reader with a schema that is 
  ' incompatible. Note the exception, determined
  ' by the particular incompatibility:
  table = GetIntegerTable()
  reader = New DataTableReader(GetStringTable())
  Try
    table.Load(reader)
  Catch ex As Exception
    Console.WriteLine(ex.GetType.Name & ":" & ex.Message())
  End Try

  Console.WriteLine(" ============================= ")
  Console.WriteLine( _
      "Load a DataTable with an IDataReader that has extra columns:")

  ' Note that loading a reader with extra columns adds
  ' the columns to the existing table, if possible:
  table = GetIntegerTable()
  reader = New DataTableReader(GetCustomers())
  table.Load(reader)
  PrintColumns(table)

  Console.WriteLine(" ============================= ")
  Console.WriteLine( _
      "Load a DataTable with an IDataReader that has missing columns:")

  ' Note that loading a reader with missing columns causes 
  ' the columns to be filled with null data, if possible:
  table = GetCustomers()
  reader = New DataTableReader(GetIntegerTable())
  table.Load(reader)
  PrintColumns(table)

  ' Demonstrate the various possibilites when loading data into
  ' a DataTable that already contains data.
  Console.WriteLine(" ============================= ")
  Console.WriteLine("Demonstrate data considerations:")
  Console.WriteLine("Current value, Original value, (RowState)")
  Console.WriteLine(" ============================= ")
  Console.WriteLine("Original table:")

  table = SetupModifiedRows()
  DisplayRowState(table)

  Console.WriteLine(" ============================= ")
  Console.WriteLine("Data in IDataReader to be loaded:")
  DisplayRowState(GetChangedCustomers())

  PerformDemo(LoadOption.OverwriteChanges)
  PerformDemo(LoadOption.PreserveChanges)
  PerformDemo(LoadOption.Upsert)

  Console.WriteLine("Press any key to continue.")
  Console.ReadKey()
End Sub

Private Sub DisplayRowState(ByVal table As DataTable)
  For i As Integer = 0 To table.Rows.Count - 1
    Dim current As Object = "--"
    Dim original As Object = "--"
    Dim rowState As DataRowState = table.Rows(i).RowState

    ' Attempt to retrieve the current value, which doesn't exist
    ' for deleted rows:
    If rowState <> DataRowState.Deleted Then
      current = table.Rows(i)("Name", DataRowVersion.Current)
    End If

    ' Attempt to retrieve the original value, which doesn't exist
    ' for added rows:
    If rowState <> DataRowState.Added Then
      original = table.Rows(i)("Name", DataRowVersion.Original)
    End If
    Console.WriteLine("{0}: {1}, {2} ({3})", i, _
      current, original, rowState)
  Next
End Sub

Private Function GetChangedCustomers() As DataTable
  ' Create sample Customers table.
  Dim table As New DataTable

  ' Create two columns, ID and Name.
  Dim idColumn As DataColumn = table.Columns.Add("ID", _
      GetType(Integer))
  table.Columns.Add("Name", GetType(String))

  ' Set the ID column as the primary key column.
  table.PrimaryKey = New DataColumn() {idColumn}

  table.Rows.Add(New Object() {0, "XXX"})
  table.Rows.Add(New Object() {1, "XXX"})
  table.Rows.Add(New Object() {2, "XXX"})
  table.Rows.Add(New Object() {3, "XXX"})
  table.Rows.Add(New Object() {4, "XXX"})
  table.AcceptChanges()
  Return table
End Function

Private Function GetCustomers() As DataTable
  ' Create sample Customers table.
  Dim table As New DataTable

  ' Create two columns, ID and Name.
  Dim idColumn As DataColumn = table.Columns.Add("ID", _
      GetType(Integer))
  table.Columns.Add("Name", GetType(String))

  ' Set the ID column as the primary key column.
  table.PrimaryKey = New DataColumn() {idColumn}

  table.Rows.Add(New Object() {0, "Mary"})
  table.Rows.Add(New Object() {1, "Andy"})
  table.Rows.Add(New Object() {2, "Peter"})
  table.AcceptChanges()
  Return table
End Function

Private Function GetIntegerTable() As DataTable
  ' Create sample table with a single Int32 column.
  Dim table As New DataTable

  Dim idColumn As DataColumn = table.Columns.Add("ID", _
      GetType(Integer))

  ' Set the ID column as the primary key column.
  table.PrimaryKey = New DataColumn() {idColumn}

  table.Rows.Add(New Object() {4})
  table.Rows.Add(New Object() {5})
  table.AcceptChanges()
  Return table
End Function

Private Function GetStringTable() As DataTable
  ' Create sample table with a single String column.
  Dim table As New DataTable

  Dim idColumn As DataColumn = table.Columns.Add("ID", _
      GetType(String))

  ' Set the ID column as the primary key column.
  table.PrimaryKey = New DataColumn() {idColumn}

  table.Rows.Add(New Object() {"Mary"})
  table.Rows.Add(New Object() {"Andy"})
  table.Rows.Add(New Object() {"Peter"})
  table.AcceptChanges()
  Return table
End Function

Private Sub PerformDemo(ByVal optionForLoad As LoadOption)

  ' Load data into a DataTable, retrieve a DataTableReader containing
  ' different data, and call the Load method. Depending on the
  ' LoadOption value passed as a parameter, this procedure displays
  ' different results in the DataTable.
  Console.WriteLine(" ============================= ")
  Console.WriteLine("table.Load(reader, {0})", optionForLoad)
  Console.WriteLine(" ============================= ")

  Dim table As DataTable = SetupModifiedRows()
  Dim reader As New DataTableReader(GetChangedCustomers())
  AddHandler table.RowChanging, New _
      DataRowChangeEventHandler(AddressOf HandleRowChanging)

  table.Load(reader, optionForLoad)
  Console.WriteLine()
  DisplayRowState(table)
End Sub

Private Sub PrintColumns( _
   ByVal table As DataTable)

  ' Loop through all the rows in the DataTableReader.
  For Each row As DataRow In table.Rows
    For Each col As DataColumn In table.Columns
      Console.Write(row(col).ToString() & " ")
    Next
    Console.WriteLine()
  Next
End Sub

Private Function SetupModifiedRows() As DataTable
  ' Fill a DataTable with customer info, and 
  ' then modify, delete, and add rows.

  Dim table As DataTable = GetCustomers()
  ' Row 0 is unmodified.
  ' Row 1 is modified.
  ' Row 2 is deleted.
  ' Row 3 is added.
  table.Rows(1)("Name") = "Sydney"
  table.Rows(2).Delete()
  Dim row As DataRow = table.NewRow
  row("ID") = 3
  row("Name") = "Melony"
  table.Rows.Add(row)

  ' Note that the code doesn't call
  ' table.AcceptChanges()
  Return table
End Function

Private Sub HandleRowChanging(ByVal sender As Object, _
      ByVal e As System.Data.DataRowChangeEventArgs)
  Console.WriteLine( _
      "RowChanging event: ID = {0}, action = {1}", e.Row("ID"), e.Action)
End Sub

備註

方法會取用所載入IDataReader的第一個結果集,而且在成功完成後,會將讀取器的位置設定為下一個結果集(如果有的話)。 LoadThe Load method consumes the first result set from the loaded IDataReader, and after successful completion, sets the reader's position to the next result set, if any. 轉換資料時, Load方法會使用與Fill方法相同的轉換規則。When converting data, the Load method uses the same conversion rules as the Fill method.

從實例載入資料時,此Load方法必須考慮三個特定的問題:架構、資料和事件作業。 IDataReaderThe Load method must take into account three specific issues when loading the data from an IDataReader instance: schema, data, and event operations. 使用此架構時,此Load方法可能會遇到條件,如下表所述。When working with the schema, the Load method may encounter conditions as described in the following table. 架構作業會針對所有匯入的結果集進行,即使不包含任何資料。The schema operations take place for all imported result sets, even those containing no data.

條件Condition 行為Behavior
DataTable沒有架構。The DataTable has no schema. 方法會根據匯入IDataReader的結果集來推斷架構。 LoadThe Load method infers the schema based on the result set from the imported IDataReader.
DataTable具有架構,但它與載入的架構不相容。The DataTable has a schema, but it is incompatible with the loaded schema. Load方法會擲回例外狀況,對應于嘗試將資料載入不相容的架構時所發生的特定錯誤。The Load method throws an exception corresponding to the particular error that occurs when attempting to load data into the incompatible schema.
架構相容,但載入的結果集架構包含不存在於中DataTable的資料行。The schemas are compatible, but the loaded result set schema contains columns that don't exist in the DataTable. 方法會將額外的資料行DataTable新增至的架構。 LoadThe Load method adds the extra columns to DataTable's schema. 如果DataTable和載入的結果集中的對應資料行與值不相容,則方法會擲回例外狀況。The method throws an exception if corresponding columns in the DataTable and the loaded result set are not value compatible. 此方法也會從所有加入之資料行的結果集中,取得條件約束資訊。The method also retrieves constraint information from the result set for all added columns. 除了 Primary Key 條件約束的案例以外,只有當目前DataTable的不包含載入作業開始時的任何資料行時,才會使用此條件約束資訊。Except for the case of Primary Key constraint, this constraint information is used only if the current DataTable does not contain any columns at the start of the load operation.
架構相容,但載入的結果集架構所包含的DataTable資料行比更少。The schemas are compatible, but the loaded result set schema contains fewer columns than does the DataTable. 如果遺漏的資料行已定義預設值,或資料行的資料類型可為 null Load ,則此方法會允許加入資料列,並以遺漏資料行的預設值或 null 值取代。If a missing column has a default value defined or the column's data type is nullable, the Load method allows the rows to be added, substituting the default or null value for the missing column. 如果沒有預設值或 null 可以使用, Load則方法會擲回例外狀況。If no default value or null can be used, then the Load method throws an exception. 如果未提供任何特定的預設值, Load方法會使用 null 值做為隱含的預設值。If no specific default value has been supplied, the Load method uses the null value as the implied default value.

在考慮資料作業方面的Load方法行為之前,請考慮在DataTable中的每個資料列都會維護目前的值和每個資料行的原始值。Before considering the behavior of the Load method in terms of data operations, consider that each row within a DataTable maintains both the current value and the original value for each column. 這些值可能相等,或者,如果資料列中的資料在填滿DataTable之後已經變更,可能會有所不同。These values may be equivalent, or may be different if the data in the row has been changed since filling the DataTable. 如需詳細資訊,請參閱資料列狀態和資料列版本See Row States and Row Versions for more information.

在這個方法呼叫中,指定LoadOption的參數會影響傳入資料的處理。In this method call, the specified LoadOption parameter influences the processing of the incoming data. 載入方法應該如何處理載入與現有資料列具有相同主鍵的資料列?How should the Load method handle loading rows that have the same primary key as existing rows? 是否應該修改目前的值、原始值或兩者?Should it modify current values, original values, or both? 這些問題和其他資訊都是由loadOption參數所控制。These issues, and more, are controlled by the loadOption parameter.

如果現有的資料列和內送資料列包含對應的主鍵值,則會使用其目前的資料列狀態值來處理資料列,否則會將它視為新的資料列。If the existing row and the incoming row contain corresponding primary key values, the row is processed using its current row state value, otherwise it's treated as a new row.

就事件作業而言, RowChanging事件會在每個資料列變更之前發生, RowChanged而事件會在每個資料列變更後發生。In terms of event operations, the RowChanging event occurs before each row is changed, and the RowChanged event occurs after each row has been changed. 在每個案例中Action ,傳遞至DataRowChangeEventArgs事件處理常式之實例的屬性,包含與事件相關聯之特定動作的資訊。In each case, the Action property of the DataRowChangeEventArgs instance passed to the event handler contains information about the particular action associated with the event. 視載入作業之前的資料列狀態而定,此動作值會有所不同。This action value varies, depending on the state of the row before the load operation. 在每個案例中,都會發生這兩個事件,每個都會有相同的動作。In each case, both events occur, and the action is the same for each. 視目前的資料列狀態而定,動作可能會套用至每個資料列的目前或原始版本,或兩者。The action may be applied to either the current or original version of each row, or both, depending on the current row state.

下表顯示使用每個LoadOption值呼叫 Load 方法時的行為,同時也會顯示這些值如何與所載入資料列的資料列狀態互動。The following table displays behavior for the Load method when called with each of the LoadOption values, and also shows how the values interact with the row state for the row being loaded. 最後一個資料列(標示為「(不存在)」)描述不符合任何現有資料列之傳入資料列的行為。The final row (labeled "(Not present)") describes the behavior for incoming rows that don't match any existing row. 下表中的每個資料格都會描述資料列內欄位的目前和原始值,以及DataRowState Load方法完成後,值的。Each cell in this table describes the current and original value for a field within a row, along with the DataRowState for the value after the Load method has completed.

現有的 DataRowStateExisting DataRowState UpsertUpsert OverwriteChangesOverwriteChanges PreserveChanges (預設行為)PreserveChanges (Default behavior)
AddedAdded 目前 = <傳入 >Current = <Incoming>

原始 =-<無法使用 >Original = -<Not available>

State = <已新增 >State = <Added>

RowAction = 變更RowAction = Change
目前 = <傳入 >Current = <Incoming>

原始 = <傳入 >Original = <Incoming>

狀態 = <未變更的 >State = <Unchanged>

RowAction = ChangeCurrentAndOriginalRowAction = ChangeCurrentAndOriginal
目前 = <現有 >Current = <Existing>

原始 = <傳入 >Original = <Incoming>

狀態 = <已修改 >State = <Modified>

RowAction = ChangeOriginalRowAction = ChangeOriginal
修改時間Modified 目前 = <傳入 >Current = <Incoming>

原始 = <現有 >Original = <Existing>

狀態 = <已修改 >State = <Modified>

RowAction = 變更RowAction = Change
目前 = <傳入 >Current = <Incoming>

原始 = <傳入 >Original = <Incoming>

狀態 = <未變更的 >State = <Unchanged>

RowAction = ChangeCurrentAndOriginalRowAction = ChangeCurrentAndOriginal
目前 = <現有 >Current = <Existing>

原始 = <傳入 >Original = <Incoming>

狀態 = <已修改 >State = <Modified>

RowAction = ChangeOriginalRowAction =ChangeOriginal
DeletedDeleted (載入不會影響已刪除的資料列)(Load does not affect deleted rows)

目前 =---Current = ---

原始 = <現有 >Original = <Existing>

狀態 = <已刪除 >State = <Deleted>

(新增包含下列特性的新資料列)(New row is added with the following characteristics)

目前 = <傳入 >Current = <Incoming>

原始 = <無法使用 >Original = <Not available>

State = <已新增 >State = <Added>

RowAction = 新增RowAction = Add
復原刪除和Undo delete and

目前 = <傳入 >Current = <Incoming>

原始 = <傳入 >Original = <Incoming>

狀態 = <未變更的 >State = <Unchanged>

RowAction = ChangeCurrentAndOriginalRowAction = ChangeCurrentAndOriginal
目前 = <無法使用 >Current = <Not available>

原始 = <傳入 >Original = <Incoming>

狀態 = <已刪除 >State = <Deleted>

RowAction = ChangeOriginalRowAction = ChangeOriginal
UnchangedUnchanged 目前 = <傳入 >Current = <Incoming>

原始 = <現有 >Original = <Existing>

如果新值與現有的值相同,則為If new value is the same as the existing value then

狀態 = <未變更的 >State = <Unchanged>

RowAction = 無RowAction = Nothing

ElseElse

狀態 = <已修改 >State = <Modified>

RowAction = 變更RowAction = Change
目前 = <傳入 >Current = <Incoming>

原始 = <傳入 >Original = <Incoming>

狀態 = <未變更的 >State = <Unchanged>

RowAction = ChangeCurrentAndOriginalRowAction = ChangeCurrentAndOriginal
目前 = <傳入 >Current = <Incoming>

原始 = <傳入 >Original = <Incoming>

狀態 = <未變更的 >State = <Unchanged>

RowAction = ChangeCurrentAndOriginalRowAction = ChangeCurrentAndOriginal
不存在)Not present) 目前 = <傳入 >Current = <Incoming>

原始 = <無法使用 >Original = <Not available>

State = <已新增 >State = <Added>

RowAction = 新增RowAction = Add
目前 = <傳入 >Current = <Incoming>

原始 = <傳入 >Original = <Incoming>

狀態 = <未變更的 >State = <Unchanged>

RowAction = ChangeCurrentAndOriginalRowAction = ChangeCurrentAndOriginal
目前 = <傳入 >Current = <Incoming>

原始 = <傳入 >Original = <Incoming>

狀態 = <未變更的 >State = <Unchanged>

RowAction = ChangeCurrentAndOriginalRowAction = ChangeCurrentAndOriginal

DataColumn的值可透過使用屬性ReadOnly (例如和AutoIncrement)來加以限制。Values in a DataColumn can be constrained through use of properties such as ReadOnly and AutoIncrement. Load方法會以與資料行屬性所定義的行為一致的方式來處理這類資料行。The Load method handles such columns in a manner that is consistent with the behavior defined by the column's properties. DataColumn的唯讀條件約束僅適用于記憶體中發生的變更。The read only constraint on a DataColumn is applicable only for changes that occur in memory. 如有需要,方法的會覆寫唯讀資料行值。LoadThe Load method's overwrites the read-only column values, if needed.

如果您在呼叫Load方法時指定 OverwriteChanges 或 PreserveChanges 選項,則會假設內送資料是DataTable來自的主要資料來源,而且 DataTable 會追蹤變更並可傳播變更回資料來源。If you specify the OverwriteChanges or PreserveChanges options when calling the Load method, then the assumption is made that the incoming data is coming from the DataTable's primary data source, and the DataTable tracks changes and can propagate the changes back to the data source. 如果您選取 Upsert 選項,則會假設資料來自其中一個次要資料來源,例如中介層元件所提供的資料,可能是由使用者改變。If you select the Upsert option, it is assumed that the data is coming from one of a secondary data source, such as data provided by a middle-tier component, perhaps altered by a user. 在此情況下,假設目的是要從中的DataTable一個或多個資料來源匯總資料,然後再將資料傳播回主要資料來源。In this case, the assumption is that the intent is to aggregate data from one or more data sources in the DataTable, and then perhaps propagate the data back to the primary data source. LoadOption參數是用來判斷要用於主鍵比較的特定資料列版本。The LoadOption parameter is used for determining the specific version of the row that is to be used for primary key comparison. 下表提供詳細資料。The table below provides the details.

載入選項Load option 用於主要索引鍵比較的 DataRow 版本DataRow version used for primary key comparison
OverwriteChanges 原始版本(如果有的話),否則為目前版本Original version, if it exists, otherwise Current version
PreserveChanges 原始版本(如果有的話),否則為目前版本Original version, if it exists, otherwise Current version
Upsert 目前的版本(如果有的話),否則為原始版本Current version, if it exists, otherwise Original version
另請參閱

Load(IDataReader, LoadOption, FillErrorEventHandler) Load(IDataReader, LoadOption, FillErrorEventHandler) Load(IDataReader, LoadOption, FillErrorEventHandler)

使用所提供的 DataTable,以資料來源的值填滿 IDataReader,使用錯誤處理委派。Fills a DataTable with values from a data source using the supplied IDataReader using an error-handling delegate.

public:
 virtual void Load(System::Data::IDataReader ^ reader, System::Data::LoadOption loadOption, System::Data::FillErrorEventHandler ^ errorHandler);
public virtual void Load (System.Data.IDataReader reader, System.Data.LoadOption loadOption, System.Data.FillErrorEventHandler errorHandler);
abstract member Load : System.Data.IDataReader * System.Data.LoadOption * System.Data.FillErrorEventHandler -> unit
override this.Load : System.Data.IDataReader * System.Data.LoadOption * System.Data.FillErrorEventHandler -> unit

參數

reader
IDataReader IDataReader IDataReader IDataReader

IDataReader,提供結果集。A IDataReader that provides a result set.

loadOption
LoadOption LoadOption LoadOption LoadOption

來自 LoadOption 列舉的值,指出已經在 DataTable 中的資料列如何與共用相同主索引鍵的傳入資料列結合。A value from the LoadOption enumeration that indicates how rows already in the DataTable are combined with incoming rows that share the same primary key.

errorHandler
FillErrorEventHandler FillErrorEventHandler FillErrorEventHandler FillErrorEventHandler

載入資料時發生錯誤,要呼叫的 FillErrorEventHandler 委派。A FillErrorEventHandler delegate to call when an error occurs while loading data.

範例

static void Main()
{
    // Attempt to load data from a data reader in which
    // the schema is incompatible with the current schema.
    // If you use exception handling, you won't get the chance
    // to examine each row, and each individual table,
    // as the Load method progresses.
    // By taking advantage of the FillErrorEventHandler delegate,
    // you can interact with the Load process as an error occurs,
    // attempting to fix the problem, or simply continuing or quitting
    // the Load process:
    DataTable table = GetIntegerTable();
    DataTableReader reader = new DataTableReader(GetStringTable());
    table.Load(reader, LoadOption.OverwriteChanges, FillErrorHandler);

    Console.WriteLine("Press any key to continue.");
    Console.ReadKey();
}

private static DataTable GetIntegerTable()
{
    // Create sample Customers table, in order
    // to demonstrate the behavior of the DataTableReader.
    DataTable table = new DataTable();

    // Create two columns, ID and Name.
    DataColumn idColumn = table.Columns.Add("ID", typeof(int));

    // Set the ID column as the primary key column.
    table.PrimaryKey = new DataColumn[] { idColumn };

    table.Rows.Add(new object[] { 4 });
    table.Rows.Add(new object[] { 5 });
    table.AcceptChanges();
    return table;
}

private static DataTable GetStringTable()
{
    // Create sample Customers table, in order
    // to demonstrate the behavior of the DataTableReader.
    DataTable table = new DataTable();

    // Create two columns, ID and Name.
    DataColumn idColumn = table.Columns.Add("ID", typeof(string));

    // Set the ID column as the primary key column.
    table.PrimaryKey = new DataColumn[] { idColumn };

    table.Rows.Add(new object[] { "Mary" });
    table.Rows.Add(new object[] { "Andy" });
    table.Rows.Add(new object[] { "Peter" });
    table.AcceptChanges();
    return table;
}

static void FillErrorHandler(object sender, FillErrorEventArgs e)
{
    // You can use the e.Errors value to determine exactly what
    // went wrong.
    if (e.Errors.GetType() == typeof(System.FormatException))
    {
        Console.WriteLine("Error when attempting to update the value: {0}", 
            e.Values[0]);
    }

    // Setting e.Continue to True tells the Load
    // method to continue trying. Setting it to False
    // indicates that an error has occurred, and the 
    // Load method raises the exception that got 
    // you here.
    e.Continue = true;
}
Sub Main()
  Dim table As New DataTable()

  ' Attempt to load data from a data reader in which
  ' the schema is incompatible with the current schema.
  ' If you use exception handling, you won't get the chance
  ' to examine each row, and each individual table,
  ' as the Load method progresses.
  ' By taking advantage of the FillErrorEventHandler delegate,
  ' you can interact with the Load process as an error occurs,
  ' attempting to fix the problem, or simply continuing or quitting
  ' the Load process:
  table = GetIntegerTable()
  Dim reader As New DataTableReader(GetStringTable())
  table.Load(reader, LoadOption.OverwriteChanges, _
      AddressOf FillErrorHandler)

  Console.WriteLine("Press any key to continue.")
  Console.ReadKey()
End Sub

Private Sub FillErrorHandler(ByVal sender As Object, _
  ByVal e As FillErrorEventArgs)
  ' You can use the e.Errors value to determine exactly what
  ' went wrong.
  If e.Errors.GetType Is GetType(System.FormatException) Then
    Console.WriteLine("Error when attempting to update the value: {0}", _
      e.Values(0))
  End If

  ' Setting e.Continue to True tells the Load
  ' method to continue trying. Setting it to False
  ' indicates that an error has occurred, and the 
  ' Load method raises the exception that got 
  ' you here.
  e.Continue = True
End Sub

Private Function GetIntegerTable() As DataTable
  ' Create sample table with a single Int32 column.
  Dim table As New DataTable

  Dim idColumn As DataColumn = table.Columns.Add("ID", GetType(Integer))

  ' Set the ID column as the primary key column.
  table.PrimaryKey = New DataColumn() {idColumn}

  table.Rows.Add(New Object() {4})
  table.Rows.Add(New Object() {5})
  table.TableName = "IntegerTable"
  table.AcceptChanges()
  Return table
End Function

Private Function GetStringTable() As DataTable
  ' Create sample table with a single String column.
  Dim table As New DataTable

  Dim idColumn As DataColumn = table.Columns.Add("ID", _
      GetType(String))

  ' Set the ID column as the primary key column.
  table.PrimaryKey = New DataColumn() {idColumn}

  table.Rows.Add(New Object() {"Mary"})
  table.Rows.Add(New Object() {"Andy"})
  table.Rows.Add(New Object() {"Peter"})
  table.AcceptChanges()
  Return table
End Function

Private Sub PrintColumns( _
   ByVal table As DataTable)

  ' Loop through all the rows in the DataTableReader.
  For Each row As DataRow In table.Rows
    For Each col As DataColumn In table.Columns
      Console.Write(row(col).ToString() & " ")
    Next
    Console.WriteLine()
  Next
End Sub

備註

方法會取用所載入IDataReader的第一個結果集,而且在成功完成後,會將讀取器的位置設定為下一個結果集(如果有的話)。 LoadThe Load method consumes the first result set from the loaded IDataReader, and after successful completion, sets the reader's position to the next result set, if any. 轉換資料時, Load方法會使用與DbDataAdapter.Fill方法相同的轉換規則。When converting data, the Load method uses the same conversion rules as the DbDataAdapter.Fill method.

從實例載入資料時,此Load方法必須考慮三個特定的問題:架構、資料和事件作業。 IDataReaderThe Load method must take into account three specific issues when loading the data from an IDataReader instance: schema, data, and event operations. 使用此架構時,此Load方法可能會遇到條件,如下表所述。When working with the schema, the Load method may encounter conditions as described in the following table. 架構作業會針對所有匯入的結果集進行,即使不包含任何資料。The schema operations take place for all imported result sets, even those containing no data.

條件Condition 行為Behavior
DataTable沒有架構。The DataTable has no schema. 方法會根據匯入IDataReader的結果集來推斷架構。 LoadThe Load method infers the schema based on the result set from the imported IDataReader.
DataTable具有架構,但它與載入的架構不相容。The DataTable has a schema, but it is incompatible with the loaded schema. Load方法會擲回例外狀況,對應于嘗試將資料載入不相容的架構時所發生的特定錯誤。The Load method throws an exception corresponding to the particular error that occurs when attempting to load data into the incompatible schema.
架構相容,但載入的結果集架構包含不存在於中DataTable的資料行。The schemas are compatible, but the loaded result set schema contains columns that don't exist in the DataTable. 方法會將額外的資料行新增至DataTable的架構。 LoadThe Load method adds the extra column(s) to DataTable's schema. 如果DataTable和載入的結果集中的對應資料行與值不相容,則方法會擲回例外狀況。The method throws an exception if corresponding columns in the DataTable and the loaded result set are not value compatible. 此方法也會從所有加入之資料行的結果集中,取得條件約束資訊。The method also retrieves constraint information from the result set for all added columns. 除了 Primary Key 條件約束的案例以外,只有當目前DataTable的不包含載入作業開始時的任何資料行時,才會使用此條件約束資訊。Except for the case of Primary Key constraint, this constraint information is used only if the current DataTable does not contain any columns at the start of the load operation.
架構相容,但載入的結果集架構所包含的DataTable資料行比更少。The schemas are compatible, but the loaded result set schema contains fewer columns than does the DataTable. 如果遺漏的資料行已定義預設值,或資料行的資料類型可為 null Load ,則此方法會允許加入資料列,並以遺漏資料行的預設值或 null 值取代。If a missing column has a default value defined or the column's data type is nullable, the Load method allows the rows to be added, substituting the default or null value for the missing column. 如果沒有預設值或 null 可以使用, Load則方法會擲回例外狀況。If no default value or null can be used, then the Load method throws an exception. 如果未提供任何特定的預設值, Load方法會使用 null 值做為隱含的預設值。If no specific default value has been supplied, the Load method uses the null value as the implied default value.

在考慮資料作業方面的Load方法行為之前,請考慮在DataTable中的每個資料列都會維護目前的值和每個資料行的原始值。Before considering the behavior of the Load method in terms of data operations, consider that each row within a DataTable maintains both the current value and the original value for each column. 這些值可能相等,或者,如果資料列中的資料在填滿DataTable之後已經變更,可能會有所不同。These values may be equivalent, or may be different if the data in the row has been changed since filling the DataTable. 如需詳細資訊,請參閱資料列狀態和資料列版本See Row States and Row Versions for more information.

在這個方法呼叫中,指定LoadOption的參數會影響傳入資料的處理。In this method call, the specified LoadOption parameter influences the processing of the incoming data. 載入方法應該如何處理載入與現有資料列具有相同主鍵的資料列?How should the Load method handle loading rows that have the same primary key as existing rows? 是否應該修改目前的值、原始值或兩者?Should it modify current values, original values, or both? 這些問題和其他資訊都是由loadOption參數所控制。These issues, and more, are controlled by the loadOption parameter.

如果現有的資料列和內送資料列包含對應的主鍵值,則會使用其目前的資料列狀態值來處理資料列,否則會將它視為新的資料列。If the existing row and the incoming row contain corresponding primary key values, the row is processed using its current row state value, otherwise it's treated as a new row.

就事件作業而言, RowChanging事件會在每個資料列變更之前發生, RowChanged而事件會在每個資料列變更後發生。In terms of event operations, the RowChanging event occurs before each row is changed, and the RowChanged event occurs after each row has been changed. 在每個案例中Action ,傳遞至DataRowChangeEventArgs事件處理常式之實例的屬性,包含與事件相關聯之特定動作的資訊。In each case, the Action property of the DataRowChangeEventArgs instance passed to the event handler contains information about the particular action associated with the event. 視載入作業之前的資料列狀態而定,此動作值會有所不同。This action value varies, depending on the state of the row before the load operation. 在每個案例中,都會發生這兩個事件,每個都會有相同的動作。In each case, both events occur, and the action is the same for each. 視目前的資料列狀態而定,動作可能會套用至每個資料列的目前或原始版本,或兩者。The action may be applied to either the current or original version of each row, or both, depending on the current row state.

下表顯示使用每個LoadOption值呼叫 Load 方法時的行為,同時也會顯示這些值如何與所載入資料列的資料列狀態互動。The following table displays behavior for the Load method when called with each of the LoadOption values, and also shows how the values interact with the row state for the row being loaded. 最後一個資料列(標示為「(不存在)」)描述不符合任何現有資料列之傳入資料列的行為。The final row (labeled "(Not present)") describes the behavior for incoming rows that don't match any existing row. 下表中的每個資料格都會描述資料列內欄位的目前和原始值,以及DataRowState Load方法完成後,值的。Each cell in this table describes the current and original value for a field within a row, along with the DataRowState for the value after the Load method has completed.

現有的 DataRowStateExisting DataRowState UpsertUpsert OverwriteChangesOverwriteChanges PreserveChanges (預設行為)PreserveChanges (Default behavior)
AddedAdded 目前 = <傳入 >Current = <Incoming>

原始 =-<無法使用 >Original = -<Not available>

State = <已新增 >State = <Added>

RowAction = 變更RowAction = Change
目前 = <傳入 >Current = <Incoming>

原始 = <傳入 >Original = <Incoming>

狀態 = <未變更的 >State = <Unchanged>

RowAction = ChangeCurrentAndOriginalRowAction = ChangeCurrentAndOriginal
目前 = <現有 >Current = <Existing>

原始 = <傳入 >Original = <Incoming>

狀態 = <已修改 >State = <Modified>

RowAction = ChangeOriginalRowAction = ChangeOriginal
修改時間Modified 目前 = <傳入 >Current = <Incoming>

原始 = <現有 >Original = <Existing>

狀態 = <已修改 >State = <Modified>

RowAction = 變更RowAction = Change
目前 = <傳入 >Current = <Incoming>

原始 = <傳入 >Original = <Incoming>

狀態 = <未變更的 >State = <Unchanged>

RowAction = ChangeCurrentAndOriginalRowAction = ChangeCurrentAndOriginal
目前 = <現有 >Current = <Existing>

原始 = <傳入 >Original = <Incoming>

狀態 = <已修改 >State = <Modified>

RowAction = ChangeOriginalRowAction =ChangeOriginal
eletedeleted (載入不會影響已刪除的資料列)(Load does not affect deleted rows)

目前 =---Current = ---

原始 = <現有 >Original = <Existing>

狀態 = <已刪除 >State = <Deleted>

(新增包含下列特性的新資料列)(New row is added with the following characteristics)

目前 = <傳入 >Current = <Incoming>

原始 = <無法使用 >Original = <Not available>

State = <已新增 >State = <Added>

RowAction = 新增RowAction = Add
復原刪除和Undo delete and

目前 = <傳入 >Current = <Incoming>

原始 = <傳入 >Original = <Incoming>

狀態 = <未變更的 >State = <Unchanged>

RowAction = ChangeCurrentAndOriginalRowAction = ChangeCurrentAndOriginal
目前 = <無法使用 >Current = <Not available>

原始 = <傳入 >Original = <Incoming>

狀態 = <已刪除 >State = <Deleted>

RowAction = ChangeOriginalRowAction = ChangeOriginal
UnchangedUnchanged 目前 = <傳入 >Current = <Incoming>

原始 = <現有 >Original = <Existing>

如果新值與現有的值相同,則為If new value is the same as the existing value then

狀態 = <未變更的 >State = <Unchanged>

RowAction = 無RowAction = Nothing

ElseElse

狀態 = <已修改 >State = <Modified>

RowAction = 變更RowAction = Change
目前 = <傳入 >Current = <Incoming>

原始 = <傳入 >Original = <Incoming>

狀態 = <未變更的 >State = <Unchanged>

RowAction = ChangeCurrentAndOriginalRowAction = ChangeCurrentAndOriginal
目前 = <傳入 >Current = <Incoming>

原始 = <傳入 >Original = <Incoming>

狀態 = <未變更的 >State = <Unchanged>

RowAction = ChangeCurrentAndOriginalRowAction = ChangeCurrentAndOriginal
不存在)Not present) 目前 = <傳入 >Current = <Incoming>

原始 = <無法使用 >Original = <Not available>

State = <已新增 >State = <Added>

RowAction = 新增RowAction = Add
目前 = <傳入 >Current = <Incoming>

原始 = <傳入 >Original = <Incoming>

狀態 = <未變更的 >State = <Unchanged>

RowAction = ChangeCurrentAndOriginalRowAction = ChangeCurrentAndOriginal
目前 = <傳入 >Current = <Incoming>

原始 = <傳入 >Original = <Incoming>

狀態 = <未變更的 >State = <Unchanged>

RowAction = ChangeCurrentAndOriginalRowAction = ChangeCurrentAndOriginal

DataColumn的值可透過使用屬性ReadOnly (例如和AutoIncrement)來加以限制。Values in a DataColumn can be constrained through use of properties such as ReadOnly and AutoIncrement. Load方法會以與資料行屬性所定義的行為一致的方式來處理這類資料行。The Load method handles such columns in a manner that is consistent with the behavior defined by the column's properties. DataColumn的唯讀條件約束僅適用于記憶體中發生的變更。The read only constraint on a DataColumn is applicable only for changes that occur in memory. 如有需要,方法的會覆寫唯讀資料行值。LoadThe Load method's overwrites the read-only column values, if needed.

如果您在呼叫Load方法時指定 OverwriteChanges 或 PreserveChanges 選項,則會假設內送資料是DataTable來自的主要資料來源,而且 DataTable 會追蹤變更並可傳播變更回資料來源。If you specify the OverwriteChanges or PreserveChanges options when calling the Load method, then the assumption is made that the incoming data is coming from the DataTable's primary data source, and the DataTable tracks changes and can propagate the changes back to the data source. 如果您選取 Upsert 選項,則會假設資料來自其中一個次要資料來源,例如中介層元件所提供的資料,可能是由使用者改變。If you select the Upsert option, it is assumed that the data is coming from one of a secondary data source, such as data provided by a middle-tier component, perhaps altered by a user. 在此情況下,假設目的是要從中的DataTable一個或多個資料來源匯總資料,然後再將資料傳播回主要資料來源。In this case, the assumption is that the intent is to aggregate data from one or more data sources in the DataTable, and then perhaps propagate the data back to the primary data source. LoadOption參數是用來判斷要用於主鍵比較的特定資料列版本。The LoadOption parameter is used for determining the specific version of the row that is to be used for primary key comparison. 下表提供詳細資料。The table below provides the details.

載入選項Load option 用於主要索引鍵比較的 DataRow 版本DataRow version used for primary key comparison
OverwriteChanges 原始版本(如果有的話),否則為目前版本Original version, if it exists, otherwise Current version
PreserveChanges 原始版本(如果有的話),否則為目前版本Original version, if it exists, otherwise Current version
Upsert 目前的版本(如果有的話),否則為原始版本Current version, if it exists, otherwise Original version

errorHandler 參數FillErrorEventHandler是委派,它會參考載入資料時發生錯誤時所呼叫的程式。The errorHandler parameter is a FillErrorEventHandler delegate that refers to a procedure that is called when an error occurs while loading data. 傳遞FillErrorEventArgs至程式的參數會提供屬性,可讓您抓取發生之錯誤的相關資訊、目前的資料列,以及正在填DataTable滿的。The FillErrorEventArgs parameter passed to the procedure provides properties that allow you to retrieve information about the error that occurred, the current row of data, and the DataTable being filled. 使用這個委派機制,而不是較簡單的 try/catch 區塊,可讓您判斷錯誤、處理情況,並視需要繼續處理。Using this delegate mechanism, rather than a simpler try/catch block, allows you to determine the error, handle the situation, and continue processing if you like. 參數提供屬性:將此屬性設定為true ,以指出您已處理錯誤,並想要繼續處理。 Continue FillErrorEventArgsThe FillErrorEventArgs parameter supplies a Continue property: set this property to true to indicate that you have handled the error and wish to continue processing. 將屬性設定為false ,表示您想要停止處理。Set the property to false to indicate that you wish to halt processing. 請注意,將屬性設定為false會使觸發問題的程式碼擲回例外狀況。Be aware that setting the property to false causes the code that triggered the problem to throw an exception.

另請參閱

適用於