DataTable.Load Метод
Определение
Важно!
Некоторые сведения относятся к предварительной версии продукта, в которую до выпуска могут быть внесены существенные изменения. Майкрософт не предоставляет никаких гарантий, явных или подразумеваемых, относительно приведенных здесь сведений.
Заполняет таблицу DataTable значениями из источника данных с помощью предоставляемого объекта IDataReader. Если объект DataTable
уже содержит строки, входящие данные из источника данных объединяются с существующими строками.
Перегрузки
Load(IDataReader) |
Заполняет таблицу DataTable значениями из источника данных с помощью предоставляемого объекта IDataReader. Если объект DataTable уже содержит строки, входящие данные из источника данных объединяются с существующими строками. |
Load(IDataReader, LoadOption) |
Заполняет таблицу DataTable значениями из источника данных с помощью предоставляемого объекта IDataReader. Если объект |
Load(IDataReader, LoadOption, FillErrorEventHandler) |
Заполняет таблицу DataTable значениями из источника данных с помощью предоставляемого объекта 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());
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
делает возможными все эти сценарии. Все перегрузки, кроме одной, для этого метода позволяют указать параметр параметра загрузки, указывающий, как строки, уже имеющиеся в , DataTable объединяются с загружаемыми строками. (Перегрузка, которая не позволяет указать поведение, использует параметр загрузки по умолчанию.) В следующей таблице описаны три параметра загрузки, предоставляемые перечислением LoadOption . В каждом случае описание указывает поведение, когда первичный ключ строки во входящих данных совпадает с первичным ключом существующей строки.
Параметр загрузки | Описание |
---|---|
PreserveChanges (по умолчанию) |
Обновления исходную версию строки со значением входящей строки. |
OverwriteChanges |
Обновления текущую и исходную версии строки значением входящей строки. |
Upsert |
Обновления текущую версию строки со значением входящей строки. |
Как правило, параметры и OverwriteChanges
предназначены для сценариев, PreserveChanges
в которых пользователю необходимо синхронизировать DataSet
и его изменения с основным источником данных. Параметр Upsert
упрощает агрегирование изменений из одного или нескольких вторичных источников данных.
Load(IDataReader)
- Исходный код:
- DataTable.cs
- Исходный код:
- DataTable.cs
- Исходный код:
- DataTable.cs
Заполняет таблицу DataTable значениями из источника данных с помощью предоставляемого объекта IDataReader. Если объект 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 строки, а событие — после изменения каждой строки. В каждом случае свойство экземпляраDataRowChangeEventArgs, переданное обработчику событий, содержит сведения о конкретном действии, Action связанном с событием. Это значение действия зависит от состояния строки перед операцией загрузки. В каждом случае происходят оба события, и действие одинаково для каждого из них. Действие может быть применено к текущей или исходной версии каждой строки или к обеим в зависимости от состояния текущей строки.
В следующей таблице показано поведение метода Load
. Последняя строка (с меткой "(Отсутствует)") описывает поведение входящих строк, которые не соответствуют ни одной существующей строке. Каждая ячейка в этой таблице описывает текущее и исходное значение для поля в строке DataRowState , а также значение для значения после Load
завершения метода. В этом случае метод не позволяет указывать параметр загрузки и использует значение по умолчанию PreserveChanges
.
Существующий DataRowState | Значения после Load метода и действие события |
---|---|
Добавлено | Текущая = <существующая> Исходный = <входящий> Состояние = <изменено> RowAction = ChangeOriginal |
Изменен | Текущая = <существующая> Исходный = <входящий> Состояние = <изменено> RowAction = ChangeOriginal |
Удаленная | Текущий = <недоступен> Исходный = <входящий> Состояние = <удалено> RowAction = ChangeOriginal |
Без изменений | Текущий = <входящий> Исходный = <входящий> Состояние = <без изменений> RowAction = ChangeCurrentAndOriginal |
(Отсутствует) | Текущий = <входящий> Исходный = <входящий> Состояние = <без изменений> RowAction = ChangeCurrentAndOriginal |
Значения в DataColumn можно ограничить с помощью таких свойств, как ReadOnly и AutoIncrement. Метод Load
обрабатывает такие столбцы в соответствии с поведением, определенным свойствами столбца. Ограничение только для DataColumn чтения для применяется только для изменений, происходящих в памяти. При Load
необходимости метод перезаписывает значения столбцов, доступные только для чтения.
Чтобы определить, какую версию поля первичного ключа следует использовать для сравнения текущей строки с входящей строкой, Load
метод использует исходную версию значения первичного ключа в строке, если оно существует. Load
В противном случае метод использует текущую версию поля первичного ключа.
См. также раздел
Применяется к
Load(IDataReader, LoadOption)
- Исходный код:
- DataTable.cs
- Исходный код:
- DataTable.cs
- Исходный код:
- DataTable.cs
Заполняет таблицу DataTable значениями из источника данных с помощью предоставляемого объекта IDataReader. Если объект 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 событие возникает после изменения каждой строки. В каждом случае свойство экземпляраDataRowChangeEventArgs, передаваемое обработчику событий, содержит сведения о конкретном действии, Action связанном с событием. Это значение действия зависит от состояния строки перед операцией загрузки. В каждом случае происходят оба события, и действие одинаково для каждого из них. Действие может применяться к текущей или исходной версии каждой строки или к обеим в зависимости от состояния текущей строки.
В следующей таблице показано поведение метода Load при вызове с каждым из LoadOption
значений, а также показано, как значения взаимодействуют с состоянием строки для загружаемой строки. Последняя строка (с меткой "(Отсутствует)") описывает поведение входящих строк, которые не соответствуют ни одной существующей строке. Каждая ячейка в этой таблице описывает текущее и исходное значение для поля в строке DataRowState , а также значение для значения после Load
завершения метода.
Существующий DataRowState | Upsert | OverwriteChanges | PreserveChanges (поведение по умолчанию) |
---|---|---|---|
Добавлено | Current = <Входящие> Original = -<Not available> Состояние = <добавлено> RowAction = Change |
Current = <Входящие> Original = <Входящие> Состояние = <без изменений> RowAction = ChangeCurrentAndOriginal |
Current = <Existing> Original = <Входящие> Состояние = <изменено> RowAction = ChangeOriginal |
Изменен | Current = <Входящие> Original = <Existing> Состояние = <изменено> RowAction = Change |
Current = <Входящие> Original = <Входящие> Состояние = <без изменений> RowAction = ChangeCurrentAndOriginal |
Current = <Existing> Original = <Входящие> Состояние = <изменено> RowAction =ChangeOriginal |
Удаленная | (Загрузка не влияет на удаленные строки) Current = --- Original = <Existing> Состояние = <Удалено> (Добавляется новая строка со следующими характеристиками) Current = <Входящие> Original = <Недоступен> Состояние = <добавлено> RowAction = Add |
Отмена удаления и Current = <Входящие> Original = <Входящие> Состояние = <без изменений> RowAction = ChangeCurrentAndOriginal |
Current = <Недоступен> Original = <Входящие> Состояние = <Удалено> RowAction = ChangeOriginal |
Без изменений | Current = <Входящие> Original = <Existing> Если новое значение совпадает с существующим, то Состояние = <без изменений> RowAction = Nothing ELSE Состояние = <изменено> RowAction = Change |
Current = <Входящие> Original = <Входящие> Состояние = <без изменений> RowAction = ChangeCurrentAndOriginal |
Current = <Входящие> Original = <Входящие> Состояние = <без изменений> RowAction = ChangeCurrentAndOriginal |
Нет) | Current = <Входящие> Original = <Недоступен> Состояние = <добавлено> RowAction = Add |
Current = <Входящие> Original = <Входящие> Состояние = <без изменений> RowAction = ChangeCurrentAndOriginal |
Current = <Входящие> Original = <Входящие> Состояние = <без изменений> RowAction = ChangeCurrentAndOriginal |
Значения в DataColumn можно ограничить с помощью таких свойств, как ReadOnly и AutoIncrement. Метод Load
обрабатывает такие столбцы способом, который соответствует поведению, определенному свойствами столбца. Ограничение только для DataColumn чтения в применяется только к изменениям, происходящим в памяти. При Load
необходимости метод перезаписывает значения столбцов, доступные только для чтения.
Если при вызове Load
метода заданы параметры OverwriteChanges или PreserveChanges, то предполагается, что входящие данные поступают из основного DataTable
источника данных, а DataTable отслеживает изменения и может распространить изменения обратно в источник данных. Если выбрать параметр Upsert, предполагается, что данные поступают из одного из вторичных источников данных, например данных, предоставляемых компонентом среднего уровня, возможно, измененных пользователем. В этом случае предполагается, что цель заключается в агрегации данных из одного или нескольких источников данных в DataTable
, а затем, возможно, распространить данные обратно в основной источник данных. Параметр LoadOption используется для определения конкретной версии строки, которая будет использоваться для сравнения первичного ключа. Подробные сведения приведены в таблице ниже.
Параметр "Загрузить" | Версия DataRow, используемая для сравнения первичного ключа |
---|---|
OverwriteChanges |
Исходная версия, если она существует, в противном случае — текущая версия |
PreserveChanges |
Исходная версия, если она существует, в противном случае — текущая версия |
Upsert |
Текущая версия, если она существует, в противном случае — исходная версия |
См. также раздел
Применяется к
Load(IDataReader, LoadOption, FillErrorEventHandler)
- Исходный код:
- DataTable.cs
- Исходный код:
- DataTable.cs
- Исходный код:
- DataTable.cs
Заполняет таблицу DataTable значениями из источника данных с помощью предоставляемого объекта IDataReader, использующего делегат для обработки ошибок.
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 событие возникает после изменения каждой строки. В каждом случае свойство экземпляраDataRowChangeEventArgs, передаваемое обработчику событий, содержит сведения о конкретном действии, Action связанном с событием. Это значение действия зависит от состояния строки перед операцией загрузки. В каждом случае происходят оба события, и действие одинаково для каждого из них. Действие может применяться к текущей или исходной версии каждой строки или к обеим в зависимости от состояния текущей строки.
В следующей таблице показано поведение метода Load при вызове с каждым из LoadOption
значений, а также показано, как значения взаимодействуют с состоянием строки для загружаемой строки. Последняя строка (с меткой "(Отсутствует)") описывает поведение входящих строк, которые не соответствуют ни одной существующей строке. Каждая ячейка в этой таблице описывает текущее и исходное значение для поля в строке DataRowState , а также значение для значения после Load
завершения метода.
Существующий DataRowState | Upsert | OverwriteChanges | PreserveChanges (поведение по умолчанию) |
---|---|---|---|
Добавлено | Current = <Входящие> Original = -<Not available> Состояние = <добавлено> RowAction = Change |
Current = <Входящие> Original = <Входящие> Состояние = <без изменений> RowAction = ChangeCurrentAndOriginal |
Current = <Existing> Original = <Входящие> Состояние = <изменено> RowAction = ChangeOriginal |
Изменен | Current = <Входящие> Original = <Existing> Состояние = <изменено> RowAction = Change |
Current = <Входящие> Original = <Входящие> Состояние = <без изменений> RowAction = ChangeCurrentAndOriginal |
Current = <Existing> Original = <Входящие> Состояние = <изменено> RowAction =ChangeOriginal |
eleted | (Загрузка не влияет на удаленные строки) Current = --- Original = <Existing> Состояние = <Удалено> (Добавляется новая строка со следующими характеристиками) Current = <Входящие> Original = <Недоступен> Состояние = <добавлено> RowAction = Add |
Отмена удаления и Current = <Входящие> Original = <Входящие> Состояние = <без изменений> RowAction = ChangeCurrentAndOriginal |
Current = <Недоступен> Original = <Входящие> Состояние = <Удалено> RowAction = ChangeOriginal |
Без изменений | Current = <Входящие> Original = <Existing> Если новое значение совпадает с существующим, то Состояние = <без изменений> RowAction = Nothing ELSE Состояние = <изменено> RowAction = Change |
Current = <Входящие> Original = <Входящие> Состояние = <без изменений> RowAction = ChangeCurrentAndOriginal |
Current = <Входящие> Original = <Входящие> Состояние = <без изменений> RowAction = ChangeCurrentAndOriginal |
Нет) | Current = <Входящие> Original = <Недоступен> Состояние = <добавлено> RowAction = Add |
Current = <Входящие> Original = <Входящие> Состояние = <без изменений> RowAction = ChangeCurrentAndOriginal |
Current = <Входящие> Original = <Входящие> Состояние = <без изменений> RowAction = ChangeCurrentAndOriginal |
Значения в DataColumn можно ограничить с помощью таких свойств, как ReadOnly и AutoIncrement. Метод 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
, код, который вызвал проблему, вызовет исключение.