DataTable.Load 方法
定义
重要
一些信息与预发行产品相关,相应产品在发行之前可能会进行重大修改。 对于此处提供的信息,Microsoft 不作任何明示或暗示的担保。
通过所提供的 IDataReader,用某个数据源的值填充 DataTable。 如果 DataTable
已经包含行,则从数据源传入的数据与现有行合并。
重载
Load(IDataReader) |
通过所提供的 IDataReader,用某个数据源的值填充 DataTable。 如果 DataTable 已经包含行,则从数据源传入的数据与现有行合并。 |
Load(IDataReader, LoadOption) |
通过所提供的 IDataReader,用某个数据源的值填充 DataTable。 如果 |
Load(IDataReader, LoadOption, FillErrorEventHandler) |
通过所提供的使用错误处理委托的 IDataReader,用某个数据源中的值填充 DataTable。 |
示例
以下示例演示了调用 Load 方法所涉及的几个问题。 首先,该示例侧重于架构问题,包括从加载 IDataReader的 推断架构,然后处理不兼容的架构,以及包含缺失列或其他列的架构。 然后,该示例侧重于数据问题,包括处理各种加载选项。
注意
此示例演示如何使用 的某个重载版本 Load
。 有关可能提供的其他示例,请参阅各个重载主题。
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
中为) 。 这些方案描述了 的标准 DataTable
用法,描述其更新和合并行为。
与 DataTable
单个主数据源同步或更新。 跟踪 DataTable
更改,允许与主数据源同步。 此外, DataTable
可以接受来自一个或多个辅助数据源的增量数据。 DataTable
不负责跟踪更改以允许与辅助数据源同步。
鉴于这两个假设数据源,用户可能需要以下行为之一:
从主数据源初始化
DataTable
。 在此方案中,用户希望使用主数据源中的值初始化空DataTable
。 稍后,用户打算将更改传播回主数据源。保留更改并从主数据源重新同步。 在此方案中,用户希望采用
DataTable
上一方案中填充的 并执行与主数据源的增量同步,并保留 在 中DataTable
所做的修改。来自辅助数据源的增量数据馈送。 在此方案中,用户希望合并来自一个或多个辅助数据源的更改,并将这些更改传播回主数据源。
方法 Load
使所有这些方案成为可能。 此方法的所有重载(其中一个重载)都允许指定 load 选项参数,指示如何将已在 中的行与正在加载的行组合在一 DataTable 起。 (不允许指定行为的重载使用默认加载选项。) 下表描述了枚举提供的 LoadOption 三个加载选项。 在每种情况下,说明都会指示传入数据中某一行的主键与现有行的主键匹配时的行为。
加载选项 | 描述 |
---|---|
PreserveChanges (默认值) |
使用传入行的值汇报行的原始版本。 |
OverwriteChanges |
使用传入行的值汇报行的当前版本和原始版本。 |
Upsert |
使用传入行的值汇报当前版本的行。 |
通常, PreserveChanges
和 OverwriteChanges
选项适用于用户需要将 及其更改与主数据源同步 DataSet
的方案。 选项 Upsert
有助于聚合来自一个或多个辅助数据源的更改。
Load(IDataReader)
- Source:
- DataTable.cs
- Source:
- DataTable.cs
- Source:
- DataTable.cs
通过所提供的 IDataReader,用某个数据源的值填充 DataTable。 如果 DataTable 已经包含行,则从数据源传入的数据与现有行合并。
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。
示例
以下示例演示了调用 Load 方法所涉及的几个问题。 首先,该示例侧重于架构问题,包括从加载 IDataReader的 推断架构,然后处理不兼容的架构,以及包含缺失列或其他列的架构。 然后,该示例调用 Load
方法,在加载操作之前和之后都显示数据。
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
注解
方法 Load 使用加载 IDataReader的第一个结果集,成功完成后,将读取器的位置设置为下一个结果集(如果有)。 转换数据时, Load
方法使用与 方法相同的转换规则 DbDataAdapter.Fill 。
从实例加载数据时, Load 方法必须考虑三个 IDataReader 特定问题:架构、数据和事件操作。 使用架构时, Load 方法可能会遇到下表中所述的条件。 架构操作针对所有导入的结果集进行,即使是那些没有数据的结果集。
条件 | 行为 |
---|---|
没有 DataTable 架构。 | 方法 Load 根据导入 IDataReader的结果集推断架构。 |
具有 DataTable 架构,但它与加载的架构不兼容。 | 方法 Load 引发与尝试将数据加载到不兼容架构时发生的特定错误对应的异常。 |
架构兼容,但加载的结果集架构包含 中不存在的 DataTable列。 | 方法 Load 将额外的列添加到 DataTable 的 架构。 如果 和加载的结果集中的对应列 DataTable 不兼容值,则 方法将引发异常。 方法还从结果集中检索所有添加列的约束信息。 除主键约束的情况外,仅当当前 DataTable 在加载操作开始时不包含任何列时,才会使用此约束信息。 |
架构是兼容的,但加载的结果集架构包含的列比 包含的 DataTable 列少。 |
如果缺少的列定义了默认值,或者该列的数据类型可为 null,则 Load 方法允许添加行,用默认值或 null 值替换缺失列。 如果没有默认值 或 null 可以使用,则 Load 方法将引发异常。 如果未提供任何特定的默认值,则 Load 方法使用 null 值作为隐含默认值。 |
在考虑方法在数据操作方面的行为 Load
之前,请考虑 内的每一 DataTable 行都维护每列的当前值和原始值。 这些值可能是等效的,或者如果行中的数据在填充 后已更改, DataTable
则这些值可能不同。 有关详细信息,请参阅 行状态和行版本。
此方法的 Load
此版本尝试保留每一行中的当前值,使原始值保持不变。 (如果要更好地控制传入数据的行为,请参阅 DataTable.Load.) 如果现有行和传入行包含相应的主键值,则使用其当前行状态值处理该行,否则将它视为新行。
就事件操作而言, RowChanging 事件发生在每一行更改之前,事件 RowChanged 在更改每行之后发生。 在每种情况下, Action 传递给事件处理程序的 DataRowChangeEventArgs 实例的 属性都包含有关与事件关联的特定操作的信息。 此操作值取决于加载操作前行的状态。 在每种情况下,这两个事件都会发生,并且每个事件的操作都是相同的。 操作可以应用于每一行的当前版本或原始版本,也可以应用于两者,具体取决于当前行状态。
下表显示了 方法的行为 Load
。 标记为“ (不存在) ”的最后一行 () 描述了与任何现有行不匹配的传入行的行为。 此表中的每个单元格都描述行内字段的当前值和原始值,以及 DataRowState 方法完成后的值的 Load
。 在这种情况下, 方法不允许指示加载选项,并使用默认值 PreserveChanges
。
现有 DataRowState | 方法和事件操作后 Load 的值 |
---|---|
已添加 | 当前 = <现有> 原始 = <传入> 状态 = <已修改> RowAction = ChangeOriginal |
修改时间 | 当前 = <现有> 原始 = <传入> 状态 = <已修改> RowAction = ChangeOriginal |
Deleted | 当前 = <不可用> 原始 = <传入> 状态 = <已删除> RowAction = ChangeOriginal |
不变 | 当前 = <传入> 原始 = <传入> 状态 = <未更改> RowAction = ChangeCurrentAndOriginal |
(不存在) | 当前 = <传入> 原始 = <传入> 状态 = <未更改> RowAction = ChangeCurrentAndOriginal |
可以通过使用 和 AutoIncrement等ReadOnly属性来约束 中的DataColumn值。 方法 Load
以与列的属性定义的行为一致的方式处理此类列。 上的 DataColumn 只读约束仅适用于内存中发生的更改。 方法 Load
的 将覆盖只读列值(如果需要)。
为了确定用于比较当前行和传入行的主键字段的版本, Load
该方法使用行内主键值的原始版本(如果存在)。 否则, Load
方法使用当前版本的主键字段。
另请参阅
适用于
Load(IDataReader, LoadOption)
- Source:
- DataTable.cs
- Source:
- DataTable.cs
- Source:
- DataTable.cs
通过所提供的 IDataReader,用某个数据源的值填充 DataTable。 如果 DataTable
已包含行,则从数据源传入的数据根据 loadOption
参数的值与现有行合并。
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
Public Sub Load (reader As IDataReader, loadOption As LoadOption)
参数
- reader
- IDataReader
提供一个或多个结果集的 IDataReader。
- loadOption
- LoadOption
LoadOption 枚举的值,指示 DataTable 中已有的行如何与共享相同主键的传入行合并。
示例
以下示例演示了调用 Load 方法所涉及的几个问题。 首先,该示例侧重于架构问题,包括从加载 IDataReader的 推断架构,然后处理不兼容的架构,以及包含缺失列或其他列的架构。 然后,该示例侧重于数据问题,包括处理各种加载选项。
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
使用加载 IDataReader的第一个结果集,成功完成后,将读取器的位置设置为下一个结果集(如果有)。 转换数据时, Load
方法使用与 方法相同的转换规则 Fill 。
从实例加载数据时, Load
方法必须考虑三个 IDataReader 特定问题:架构、数据和事件操作。 使用架构时, Load
方法可能会遇到下表中所述的条件。 架构操作针对所有导入的结果集进行,即使是那些没有数据的结果集。
条件 | 行为 |
---|---|
没有 DataTable 架构。 | 方法 Load 根据导入 IDataReader的结果集推断架构。 |
具有 DataTable 架构,但它与加载的架构不兼容。 | 方法 Load 引发与尝试将数据加载到不兼容架构时发生的特定错误对应的异常。 |
架构兼容,但加载的结果集架构包含 中不存在的 DataTable 列。 |
方法 Load 将额外的列添加到 DataTable 的 架构。 如果 和加载的结果集中的对应列 DataTable 不兼容值,则 方法将引发异常。 方法还从结果集中检索所有添加列的约束信息。 除主键约束的情况外,仅当当前 DataTable 在加载操作开始时不包含任何列时,才会使用此约束信息。 |
架构是兼容的,但加载的结果集架构包含的列比 包含的 DataTable 列少。 |
如果缺失列定义了默认值,或者该列的数据类型可为 null,则 Load 方法允许添加行,用默认值或 null 值替换缺失列。 如果不能使用默认值或 null,则 Load 该方法将引发异常。 如果未提供任何特定的默认值,则 Load 方法使用 null 值作为隐式默认值。 |
在考虑方法在数据操作方面的行为 Load
之前,请考虑 内的每一 DataTable 行都维护每列的当前值和原始值。 这些值可能是等效的,或者如果行中的数据在填充 后已更改, DataTable
则这些值可能不同。 有关详细信息 ,请参阅行状态和行版本 。
在此方法调用中,指定的 LoadOption 参数会影响传入数据的处理。 Load 方法应如何处理加载主键与现有行相同的行? 它应该修改当前值和/或原始值? 这些问题等都由 loadOption
参数控制。
如果现有行和传入行包含相应的主键值,则使用其当前行状态值处理该行,否则会将其视为新行。
就事件操作而言, RowChanging 事件发生在每一行更改之前,事件 RowChanged 在更改每行之后发生。 在每种情况下, Action 传递给事件处理程序的 DataRowChangeEventArgs 实例的 属性都包含有关与事件关联的特定操作的信息。 此操作值因加载操作前行的状态而异。 在每种情况下,这两个事件都会发生,并且每个事件的操作都是相同的。 操作可以应用于每一行的当前版本或原始版本,也可以应用于两者,具体取决于当前行状态。
下表显示了使用每个 LoadOption
值调用 Load 方法时的行为,还显示了值与所加载行的行状态的交互方式。 标记为“ (不存在) ”的最后一行 () 描述了与任何现有行不匹配的传入行的行为。 此表中的每个单元格都描述行内字段的当前值和原始值,以及 DataRowState 方法完成后的值的 Load
。
现有 DataRowState | Upsert | OverwriteChanges | PreserveChanges (默认行为) |
---|---|---|---|
已添加 | 当前 = <传入> 原始 = -<不可用> State = <已添加> RowAction = Change |
当前 = <传入> 原始 = <传入> 状态 = <未更改> RowAction = ChangeCurrentAndOriginal |
当前 = <现有> 原始 = <传入> 状态 = <已修改> RowAction = ChangeOriginal |
修改时间 | 当前 = <传入> 原始 = <现有> 状态 = <已修改> RowAction = Change |
当前 = <传入> 原始 = <传入> 状态 = <未更改> RowAction = ChangeCurrentAndOriginal |
当前 = <现有> 原始 = <传入> 状态 = <已修改> RowAction =ChangeOriginal |
Deleted | (加载不会影响已删除的行) 当前 = --- 原始 = <现有> 状态 = <已删除> (添加了具有以下特征的新行) 当前 = <传入> 原始 = <不可用> State = <已添加> RowAction = Add |
撤消删除 和 当前 = <传入> 原始 = <传入> 状态 = <未更改> RowAction = ChangeCurrentAndOriginal |
当前 = <不可用> 原始 = <传入> 状态 = <已删除> RowAction = ChangeOriginal |
不变 | 当前 = <传入> 原始 = <现有> 如果新值与现有值相同,则 状态 = <未更改> RowAction = Nothing Else 状态 = <已修改> RowAction = Change |
当前 = <传入> 原始 = <传入> 状态 = <未更改> RowAction = ChangeCurrentAndOriginal |
当前 = <传入> 原始 = <传入> 状态 = <未更改> RowAction = ChangeCurrentAndOriginal |
不存在) | 当前 = <传入> 原始 = <不可用> State = <已添加> RowAction = Add |
当前 = <传入> 原始 = <传入> 状态 = <未更改> RowAction = ChangeCurrentAndOriginal |
当前 = <传入> 原始 = <传入> 状态 = <未更改> RowAction = ChangeCurrentAndOriginal |
可以通过使用 和 AutoIncrement等ReadOnly属性来约束 中的DataColumn值。 方法 Load
以与列的属性定义的行为一致的方式处理此类列。 上的 DataColumn 只读约束仅适用于内存中发生的更改。 方法 Load
的 将覆盖只读列值(如果需要)。
如果在调用 Load
方法时指定 OverwriteChanges 或 PreserveChanges 选项,则假定传入的数据来自 DataTable
的主数据源,并且 DataTable 会跟踪更改,并且可以将更改传播回数据源。 如果选择 Upsert 选项,则假定数据来自辅助数据源之一,例如中间层组件提供的数据,可能由用户更改。 在这种情况下,假设目的是聚合 中一个或多个数据源中的数据 DataTable
,然后可能将数据传播回主数据源。 参数 LoadOption 用于确定要用于主键比较的行的特定版本。 下表提供了详细信息。
加载选项 | 用于主键比较的 DataRow 版本 |
---|---|
OverwriteChanges |
原始版本(如果存在),否则为当前版本 |
PreserveChanges |
原始版本(如果存在),否则为当前版本 |
Upsert |
当前版本(如果存在),否则为原始版本 |
另请参阅
适用于
Load(IDataReader, LoadOption, FillErrorEventHandler)
- Source:
- DataTable.cs
- Source:
- DataTable.cs
- Source:
- DataTable.cs
通过所提供的使用错误处理委托的 IDataReader,用某个数据源中的值填充 DataTable。
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);
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
Public Overridable Sub Load (reader As IDataReader, loadOption As LoadOption, errorHandler As FillErrorEventHandler)
参数
- reader
- IDataReader
提供结果集的 IDataReader。
- loadOption
- LoadOption
LoadOption 枚举的值,指示 DataTable 中已有的行如何与共享相同主键的传入行合并。
- errorHandler
- FillErrorEventHandler
加载数据时出现错误的情况下要调用的 FillErrorEventHandler 委托。
示例
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
注解
方法 Load
使用加载 IDataReader的第一个结果集,成功完成后,将读取器的位置设置为下一个结果集(如果有)。 转换数据时, Load
方法使用与 方法相同的转换规则 DbDataAdapter.Fill 。
从实例加载数据时, Load
方法必须考虑三个 IDataReader 特定问题:架构、数据和事件操作。 使用架构时, Load
方法可能会遇到下表中所述的条件。 架构操作针对所有导入的结果集进行,即使是那些没有数据的结果集。
条件 | 行为 |
---|---|
没有 DataTable 架构。 | 方法 Load 根据导入 IDataReader的结果集推断架构。 |
具有 DataTable 架构,但它与加载的架构不兼容。 | 方法 Load 引发与尝试将数据加载到不兼容架构时发生的特定错误对应的异常。 |
架构兼容,但加载的结果集架构包含 中不存在的 DataTable 列。 |
方法 Load 将额外的列 () 添加到 DataTable 的 架构。 如果 和加载的结果集中的对应列 DataTable 不兼容值,则 方法将引发异常。 方法还从结果集中检索所有添加列的约束信息。 除主键约束的情况外,仅当当前 DataTable 在加载操作开始时不包含任何列时,才会使用此约束信息。 |
架构是兼容的,但加载的结果集架构包含的列比 包含的 DataTable 列少。 |
如果缺失列定义了默认值,或者该列的数据类型可为 null,则 Load 方法允许添加行,用默认值或 null 值替换缺失列。 如果不能使用默认值或 null,则 Load 该方法将引发异常。 如果未提供任何特定的默认值,则 Load 方法使用 null 值作为隐式默认值。 |
在考虑方法在数据操作方面的行为 Load
之前,请考虑 内的每一 DataTable 行都维护每列的当前值和原始值。 这些值可能是等效的,或者如果行中的数据在填充 后已更改, DataTable
则这些值可能不同。 有关详细信息 ,请参阅行状态和行版本 。
在此方法调用中,指定的 LoadOption 参数会影响传入数据的处理。 Load 方法应如何处理加载主键与现有行相同的行? 它应该修改当前值和/或原始值? 这些问题等都由 loadOption
参数控制。
如果现有行和传入行包含相应的主键值,则使用其当前行状态值处理该行,否则会将其视为新行。
就事件操作而言, RowChanging 事件发生在每一行更改之前,事件 RowChanged 在更改每行之后发生。 在每种情况下, Action 传递给事件处理程序的 DataRowChangeEventArgs 实例的 属性都包含有关与事件关联的特定操作的信息。 此操作值因加载操作前行的状态而异。 在每种情况下,这两个事件都会发生,并且每个事件的操作都是相同的。 操作可以应用于每一行的当前版本或原始版本,也可以应用于两者,具体取决于当前行状态。
下表显示了使用每个 LoadOption
值调用 Load 方法时的行为,还显示了值与所加载行的行状态的交互方式。 标记为“ (不存在) ”的最后一行 () 描述了与任何现有行不匹配的传入行的行为。 此表中的每个单元格都描述行内字段的当前值和原始值,以及 DataRowState 方法完成后的值的 Load
。
现有 DataRowState | Upsert | OverwriteChanges | PreserveChanges (默认行为) |
---|---|---|---|
已添加 | 当前 = <传入> 原始 = -<不可用> State = <已添加> RowAction = Change |
当前 = <传入> 原始 = <传入> 状态 = <未更改> RowAction = ChangeCurrentAndOriginal |
当前 = <现有> 原始 = <传入> 状态 = <已修改> RowAction = ChangeOriginal |
修改时间 | 当前 = <传入> 原始 = <现有> 状态 = <已修改> RowAction = Change |
当前 = <传入> 原始 = <传入> 状态 = <未更改> RowAction = ChangeCurrentAndOriginal |
当前 = <现有> 原始 = <传入> 状态 = <已修改> RowAction =ChangeOriginal |
eleted | (加载不会影响已删除的行) 当前 = --- 原始 = <现有> 状态 = <已删除> (添加了具有以下特征的新行) 当前 = <传入> 原始 = <不可用> State = <已添加> RowAction = Add |
撤消删除 和 当前 = <传入> 原始 = <传入> 状态 = <未更改> RowAction = ChangeCurrentAndOriginal |
当前 = <不可用> 原始 = <传入> 状态 = <已删除> RowAction = ChangeOriginal |
不变 | 当前 = <传入> 原始 = <现有> 如果新值与现有值相同,则 状态 = <未更改> RowAction = Nothing Else 状态 = <已修改> RowAction = Change |
当前 = <传入> 原始 = <传入> 状态 = <未更改> RowAction = ChangeCurrentAndOriginal |
当前 = <传入> 原始 = <传入> 状态 = <未更改> RowAction = ChangeCurrentAndOriginal |
不存在) | 当前 = <传入> 原始 = <不可用> State = <已添加> RowAction = Add |
当前 = <传入> 原始 = <传入> 状态 = <未更改> RowAction = ChangeCurrentAndOriginal |
当前 = <传入> 原始 = <传入> 状态 = <未更改> RowAction = ChangeCurrentAndOriginal |
可以通过使用 和 AutoIncrement等ReadOnly属性来约束 中的DataColumn值。 方法 Load
以与列的属性定义的行为一致的方式处理此类列。 上的 DataColumn 只读约束仅适用于内存中发生的更改。 方法 Load
的 将覆盖只读列值(如果需要)。
如果在调用 Load
方法时指定 OverwriteChanges 或 PreserveChanges 选项,则假定传入的数据来自 DataTable
的主数据源,并且 DataTable 会跟踪更改,并且可以将更改传播回数据源。 如果选择 Upsert 选项,则假定数据来自辅助数据源之一,例如中间层组件提供的数据,可能由用户更改。 在这种情况下,假设目的是聚合 中一个或多个数据源中的数据 DataTable
,然后可能将数据传播回主数据源。 参数 LoadOption 用于确定要用于主键比较的行的特定版本。 下表提供了详细信息。
加载选项 | 用于主键比较的 DataRow 版本 |
---|---|
OverwriteChanges |
原始版本(如果存在),否则为当前版本 |
PreserveChanges |
原始版本(如果存在),否则为当前版本 |
Upsert |
当前版本(如果存在),否则为原始版本 |
errorHandler
参数是一个FillErrorEventHandler委托,它引用加载数据时发生错误时调用的过程。 FillErrorEventArgs传递给过程的参数提供属性,使你能够检索有关发生的错误、当前数据行和DataTable正在填充的信息。 使用此委托机制(而不是更简单的 try/catch 块)可以确定错误、处理情况,并根据需要继续处理。 参数 FillErrorEventArgs 提供属性 Continue :将此属性设置为 true
以指示已处理错误并希望继续处理。 将 属性设置为 false
以指示要停止处理。 请注意,将 属性设置为 false
会导致触发问题的代码引发异常。