Aktualizowanie źródeł danych za pomocą elementów DataAdapters
Metoda Update
metody jest wywoływana DataAdapter w celu rozwiązania zmian z DataSet powrotem do źródła danych. Metoda Update
, podobnie jak Fill
metoda, przyjmuje jako argumenty wystąpienie DataSet
obiektu i opcjonalną DataTable nazwę lub DataTable
obiekt. Wystąpienie DataSet
to DataSet
, które zawiera wprowadzone zmiany, oraz DataTable
identyfikuje tabelę, z której mają zostać pobrane zmiany. Jeśli nie DataTable
zostanie określony, zostanie użyty pierwszy DataTable
w elemecie DataSet
.
Podczas wywoływania Update
metody DataAdapter
funkcja analizuje wprowadzone zmiany i wykonuje odpowiednie polecenie (INSERT, UPDATE lub DELETE). W przypadku DataAdapter
napotkania zmiany na DataRow, używa InsertCommandmetody , UpdateCommandlub DeleteCommand do przetworzenia zmiany. Dzięki temu można zmaksymalizować wydajność aplikacji ADO.NET, określając składnię poleceń w czasie projektowania i, jeśli to możliwe, za pomocą procedur składowanych. Przed wywołaniem Update
polecenia należy jawnie ustawić polecenie . Jeśli Update
jest wywoływana i odpowiednie polecenie nie istnieje dla określonej aktualizacji (na przykład nie DeleteCommand
dla usuniętych wierszy), zgłaszany jest wyjątek.
Uwaga
Jeśli używasz procedur składowanych programu SQL Server do edytowania lub usuwania danych przy użyciu elementu DataAdapter
, upewnij się, że nie używasz funkcji SET NOCOUNT ON w definicji procedury składowanej. Powoduje to, że liczba wierszy, których dotyczy problem, zwraca wartość zero, co DataAdapter
interpretuje jako konflikt współbieżności. W tym przypadku zostanie zgłoszony element DBConcurrencyException .
Parametry polecenia mogą służyć do określania wartości wejściowych i wyjściowych instrukcji SQL lub procedury składowanej dla każdego zmodyfikowanego wiersza w obiekcie DataSet
. Aby uzyskać więcej informacji, zobacz DataAdapter Parameters (Parametry elementu DataAdapter).
Uwaga
Ważne jest, aby zrozumieć różnicę między usunięciem wiersza w obiekcie DataTable a usunięciem wiersza. Po wywołaniu Remove
metody or RemoveAt
wiersz zostanie natychmiast usunięty. Jeśli następnie przekażesz DataTable
element lub do metody DataAdapter
i DataSet
Update
, wszystkie odpowiednie wiersze w źródle danych zaplecza nie będą miały wpływu. W przypadku użycia metody wiersz pozostaje w elemecie Delete
DataTable
i jest oznaczony do usunięcia. Jeśli następnie przekażesz metodę DataTable
DataAdapter
lub DataSet
do metody i Update
, odpowiedni wiersz w źródle danych zaplecza zostanie usunięty.
DataTable
Jeśli mapy do lub są generowane na podstawie pojedynczej tabeli bazy danych, możesz skorzystać z DbCommandBuilder obiektu , aby automatycznie wygenerować DeleteCommand
obiekty , InsertCommand
i UpdateCommand
dla obiektu DataAdapter
. Aby uzyskać więcej informacji, zobacz Generowanie poleceń za pomocą poleceń CommandBuilders.
Używanie elementu UpdatedRowSource do mapowania wartości na zestaw danych
Możesz kontrolować, jak wartości zwracane ze źródła danych są mapowane z powrotem na DataTable
następujące wywołanie metody Update obiektu DataAdapter
przy użyciu UpdatedRowSource właściwości DbCommand obiektu . Ustawiając UpdatedRowSource
właściwość na jedną z UpdateRowSource wartości wyliczenia, możesz kontrolować, czy parametry wyjściowe zwracane przez DataAdapter
polecenia są ignorowane, czy stosowane do zmienionego wiersza w obiekcie DataSet
. Można również określić, czy pierwszy zwrócony wiersz (jeśli istnieje) jest stosowany do zmienionego wiersza w pliku DataTable
.
W poniższej tabeli opisano różne wartości UpdateRowSource
wyliczenia i sposób ich wpływu na zachowanie polecenia używanego z elementem DataAdapter
.
UpdatedRowSource— Wyliczenie | opis |
---|---|
Both | Parametry wyjściowe i pierwszy wiersz zwróconego zestawu wyników mogą być mapowane na zmieniony wiersz w pliku DataSet . |
FirstReturnedRecord | Tylko dane w pierwszym wierszu zwróconego zestawu wyników mogą być mapowane na zmieniony wiersz w pliku DataSet . |
None | Wszystkie parametry wyjściowe lub wiersze zwróconego zestawu wyników są ignorowane. |
OutputParameters | Tylko parametry wyjściowe mogą być mapowane na zmieniony wiersz w pliku DataSet . |
Metoda Update
usuwa zmiany ze źródłem danych, jednak inni klienci mogli zmodyfikować dane w źródle danych od czasu ostatniego wypełnienia elementu DataSet
. Aby odświeżyć dane DataSet
przy użyciu bieżących danych, użyj DataAdapter
metody i Fill
. Nowe wiersze zostaną dodane do tabeli, a zaktualizowane informacje zostaną włączone do istniejących wierszy. Metoda Fill
określa, czy nowy wiersz zostanie dodany, czy istniejący wiersz zostanie zaktualizowany, sprawdzając wartości klucza podstawowego wierszy w DataSet
tabeli i wiersze zwrócone przez SelectCommand
element . Fill
Jeśli metoda napotka wartość klucza podstawowego dla wiersza wDataSet
, który pasuje do wartości klucza podstawowego z wiersza w wynikach zwróconych przez SelectCommand
, aktualizuje istniejący wiersz z informacjami z wiersza zwróconego przez SelectCommand
i ustawia RowState istniejący wiersz na Unchanged
wartość . Jeśli wiersz zwracany przez SelectCommand
element ma wartość klucza podstawowego, która nie jest zgodna z żadnymi wartościami klucza podstawowego wierszy w DataSet
tabeli , Fill
metoda dodaje nowy wiersz z wartością Unchanged
RowState
.
Uwaga
SelectCommand
Jeśli funkcja zwraca wyniki sprzężenia ZEWNĘTRZNEgo, DataAdapter
parametr nie ustawi PrimaryKey
wartości wynikowej DataTable
. Należy zdefiniować PrimaryKey
samodzielnie, aby upewnić się, że zduplikowane wiersze są prawidłowo rozpoznawane. Aby uzyskać więcej informacji, zobacz Definiowanie kluczy podstawowych.
Aby obsłużyć wyjątki, które mogą wystąpić podczas wywoływania metody, można użyć RowUpdated
zdarzenia do reagowania na błędy aktualizacji wierszy w miarę ich występowania (zobacz Obsługa zdarzeń DataAdapter) lub można ustawić DataAdapter.ContinueUpdateOnError
wartość na true
wartość przed wywołaniem Update
Update
metody i odpowiedzieć na informacje o błędzie przechowywane we RowError
właściwości określonego wiersza po zakończeniu aktualizacji (zobacz Informacje o błędzie wiersza).
Uwaga
Wywołanie AcceptChanges
metody , DataTable
DataSet
lub DataRow
spowoduje zastąpienie wszystkich Original
wartości obiektu DataRow
wartościami Current
dla elementu DataRow
. Jeśli wartości pól identyfikujące wiersz jako unikatowy zostały zmodyfikowane, po wywołaniu AcceptChanges
Original
wartości nie będą już zgodne z wartościami w źródle danych. AcceptChanges
element jest wywoływany automatycznie dla każdego wiersza podczas wywołania metody Update klasy DataAdapter
. Oryginalne wartości można zachować podczas wywołania metody Update, ustawiając AcceptChangesDuringUpdate
najpierw właściwość DataAdapter
właściwości na false lub tworząc program obsługi zdarzeń dla RowUpdated
zdarzenia i ustawiając Status wartość SkipCurrentRow. Aby uzyskać więcej informacji, zobacz Scalanie zawartości zestawu danych i obsługa zdarzeń dataAdapter.
Przykład
W poniższych przykładach pokazano, jak wykonać aktualizacje zmodyfikowanych wierszy, jawnie ustawiając UpdateCommand
DataAdapter
metodę i wywołując metodę Update
. Zwróć uwagę, że parametr określony w klauzuli WHERE instrukcji UPDATE jest ustawiony na użycie Original
wartości SourceColumn
. Jest to ważne, ponieważ Current
wartość mogła zostać zmodyfikowana i może być niezgodna z wartością w źródle danych. Wartość Original
to wartość, która została użyta do wypełnienia DataTable
elementu ze źródła danych.
static void AdapterUpdate(string connectionString)
{
using (SqlConnection connection =
new(connectionString))
{
SqlDataAdapter dataAdapter = new(
"SELECT CategoryID, CategoryName FROM Categories",
connection)
{
UpdateCommand = new SqlCommand(
"UPDATE Categories SET CategoryName = @CategoryName " +
"WHERE CategoryID = @CategoryID", connection)
};
dataAdapter.UpdateCommand.Parameters.Add(
"@CategoryName", SqlDbType.NVarChar, 15, "CategoryName");
SqlParameter parameter = dataAdapter.UpdateCommand.Parameters.Add(
"@CategoryID", SqlDbType.Int);
parameter.SourceColumn = "CategoryID";
parameter.SourceVersion = DataRowVersion.Original;
DataTable categoryTable = new();
dataAdapter.Fill(categoryTable);
DataRow categoryRow = categoryTable.Rows[0];
categoryRow["CategoryName"] = "New Beverages";
dataAdapter.Update(categoryTable);
Console.WriteLine("Rows after update.");
foreach (DataRow row in categoryTable.Rows)
{
{
Console.WriteLine("{0}: {1}", row[0], row[1]);
}
}
}
}
Private Sub AdapterUpdate(ByVal connectionString As String)
Using connection As SqlConnection = New SqlConnection( _
connectionString)
Dim adapter As SqlDataAdapter = New SqlDataAdapter( _
"SELECT CategoryID, CategoryName FROM dbo.Categories", _
connection)
adapter.UpdateCommand = New SqlCommand( _
"UPDATE Categories SET CategoryName = @CategoryName " & _
"WHERE CategoryID = @CategoryID", connection)
adapter.UpdateCommand.Parameters.Add( _
"@CategoryName", SqlDbType.NVarChar, 15, "CategoryName")
Dim parameter As SqlParameter = _
adapter.UpdateCommand.Parameters.Add( _
"@CategoryID", SqlDbType.Int)
parameter.SourceColumn = "CategoryID"
parameter.SourceVersion = DataRowVersion.Original
Dim categoryTable As New DataTable
adapter.Fill(categoryTable)
Dim categoryRow As DataRow = categoryTable.Rows(0)
categoryRow("CategoryName") = "New Beverages"
adapter.Update(categoryTable)
Console.WriteLine("Rows after update.")
Dim row As DataRow
For Each row In categoryTable.Rows
Console.WriteLine("{0}: {1}", row(0), row(1))
Next
End Using
End Sub
Kolumny autoinkrementacji
Jeśli tabele ze źródła danych mają kolumny automatycznego zwiększania, możesz wypełnić kolumny w DataSet
elemecie , zwracając wartość automatycznego przyrostu jako parametr wyjściowy procedury składowanej i mapując ją na kolumnę w tabeli, zwracając wartość auto-inkrementacji w pierwszym wierszu zestawu wyników zwróconego przez procedurę składowaną lub instrukcję SQL. lub za pomocą RowUpdated
zdarzenia DataAdapter
, aby wykonać dodatkową instrukcję SELECT. Aby uzyskać więcej informacji i przykład, zobacz Pobieranie tożsamości lub wartości autonumerowania.
Kolejność wstawiania, aktualizacji i usuwania
W wielu okolicznościach ważna jest kolejność wysyłania zmian wprowadzonych za pośrednictwem DataSet
elementu do źródła danych. Jeśli na przykład wartość klucza podstawowego dla istniejącego wiersza zostanie zaktualizowana, a nowy wiersz został dodany przy użyciu nowej wartości klucza podstawowego jako klucza obcego, ważne jest, aby przetworzyć aktualizację przed wstawieniem.
Możesz użyć Select
metody , DataTable
aby zwrócić tablicę DataRow
, która odwołuje się tylko do wierszy z określonym RowState
elementem . Następnie można przekazać zwróconą DataRow
tablicę do Update
metody DataAdapter
, aby przetworzyć zmodyfikowane wiersze. Określając podzestaw wierszy do zaktualizowania, można kontrolować kolejność przetwarzania wstawiania, aktualizacji i usuwania.
Na przykład poniższy kod gwarantuje, że usunięte wiersze tabeli są najpierw przetwarzane, a następnie zaktualizowane wiersze, a następnie wstawione wiersze.
Dim table As DataTable = dataSet.Tables("Customers")
' First process deletes.
dataSet.Update(table.Select(Nothing, Nothing, _
DataViewRowState.Deleted))
' Next process updates.
adapter.Update(table.Select(Nothing, Nothing, _
DataViewRowState.ModifiedCurrent))
' Finally, process inserts.
adapter.Update(table.Select(Nothing, Nothing, _
DataViewRowState.Added))
DataTable table = dataSet.Tables["Customers"];
// First process deletes.
adapter.Update(table.Select(null, null, DataViewRowState.Deleted));
// Next process updates.
adapter.Update(table.Select(null, null,
DataViewRowState.ModifiedCurrent));
// Finally, process inserts.
adapter.Update(table.Select(null, null, DataViewRowState.Added));
Używanie elementu DataAdapter do pobierania i aktualizowania danych
Aby pobrać i zaktualizować dane, możesz użyć elementu DataAdapter.
W przykładzie użyto elementu DataAdapter.AcceptChangesDuringFill w celu sklonowania danych w bazie danych. Jeśli właściwość jest ustawiona jako false, funkcja AcceptChanges nie jest wywoływana podczas wypełniania tabeli, a nowo dodane wiersze są traktowane jako wstawione wiersze. W tym przykładzie użyto tych wierszy do wstawienia nowych wierszy do bazy danych.
W przykładach użyto elementu DataAdapter.TableMappings do zdefiniowania mapowania między tabelą źródłową a tabelą DataTable.
W przykładzie użyto elementu DataAdapter.FillLoadOption, aby określić sposób wypełniania tabeli DataTable z elementu DbDataReader. Podczas tworzenia tabeli DataTable można zapisywać dane tylko z bazy danych do bieżącej wersji lub oryginalnej wersji, ustawiając właściwość jako LoadOption.Upsert lub LoadOption.PreserveChanges.
Przykład zaktualizuje również tabelę przy użyciu polecenia DbDataAdapter.UpdateBatchSize w celu wykonywania operacji wsadowych.
Przed skompilowanie i uruchomieniem przykładowej bazy danych należy utworzyć przykładową bazę danych:
USE [master]
GO
CREATE DATABASE [MySchool]
GO
USE [MySchool]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Course]([CourseID] [nvarchar](10) NOT NULL,
[Year] [smallint] NOT NULL,
[Title] [nvarchar](100) NOT NULL,
[Credits] [int] NOT NULL,
[DepartmentID] [int] NOT NULL,
CONSTRAINT [PK_Course] PRIMARY KEY CLUSTERED
(
[CourseID] ASC,
[Year] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]) ON [PRIMARY]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Department]([DepartmentID] [int] IDENTITY(1,1) NOT NULL,
[Name] [nvarchar](50) NOT NULL,
[Budget] [money] NOT NULL,
[StartDate] [datetime] NOT NULL,
[Administrator] [int] NULL,
CONSTRAINT [PK_Department] PRIMARY KEY CLUSTERED
(
[DepartmentID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]) ON [PRIMARY]
GO
INSERT [dbo].[Course] ([CourseID], [Year], [Title], [Credits], [DepartmentID]) VALUES (N'C1045', 2012, N'Calculus', 4, 7)
INSERT [dbo].[Course] ([CourseID], [Year], [Title], [Credits], [DepartmentID]) VALUES (N'C1061', 2012, N'Physics', 4, 1)
INSERT [dbo].[Course] ([CourseID], [Year], [Title], [Credits], [DepartmentID]) VALUES (N'C2021', 2012, N'Composition', 3, 2)
INSERT [dbo].[Course] ([CourseID], [Year], [Title], [Credits], [DepartmentID]) VALUES (N'C2042', 2012, N'Literature', 4, 2)
SET IDENTITY_INSERT [dbo].[Department] ON
INSERT [dbo].[Department] ([DepartmentID], [Name], [Budget], [StartDate], [Administrator]) VALUES (1, N'Engineering', 350000.0000, CAST(0x0000999C00000000 AS DateTime), 2)
INSERT [dbo].[Department] ([DepartmentID], [Name], [Budget], [StartDate], [Administrator]) VALUES (2, N'English', 120000.0000, CAST(0x0000999C00000000 AS DateTime), 6)
INSERT [dbo].[Department] ([DepartmentID], [Name], [Budget], [StartDate], [Administrator]) VALUES (4, N'Economics', 200000.0000, CAST(0x0000999C00000000 AS DateTime), 4)
INSERT [dbo].[Department] ([DepartmentID], [Name], [Budget], [StartDate], [Administrator]) VALUES (7, N'Mathematics', 250024.0000, CAST(0x0000999C00000000 AS DateTime), 3)
SET IDENTITY_INSERT [dbo].[Department] OFF
ALTER TABLE [dbo].[Course] WITH CHECK ADD CONSTRAINT [FK_Course_Department] FOREIGN KEY([DepartmentID])
REFERENCES [dbo].[Department] ([DepartmentID])
GO
ALTER TABLE [dbo].[Course] CHECK CONSTRAINT [FK_Course_Department]
GO
using System;
using System.Data;
using System.Data.Common;
using System.Data.SqlClient;
using System.Linq;
using CSDataAdapterOperations.Properties;
namespace CSDataAdapterOperations.Properties {
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
public static Settings Default {
get {
return defaultInstance;
}
}
[global::System.Configuration.ApplicationScopedSettingAttribute()]
public string MySchoolConnectionString {
get {
return ((string)(this["MySchoolConnectionString"]));
}
}
}
}
class Program {
static void Main(string[] args) {
Settings settings = new Settings();
// Copy the data from the database. Get the table Department and Course from the database.
String selectString = @"SELECT [DepartmentID],[Name],[Budget],[StartDate],[Administrator]
FROM [MySchool].[dbo].[Department];
SELECT [CourseID],@Year as [Year],Max([Title]) as [Title],
Max([Credits]) as [Credits],Max([DepartmentID]) as [DepartmentID]
FROM [MySchool].[dbo].[Course]
Group by [CourseID]";
DataSet mySchool = new DataSet();
SqlCommand selectCommand = new SqlCommand(selectString);
SqlParameter parameter = selectCommand.Parameters.Add("@Year", SqlDbType.SmallInt, 2);
parameter.Value = new Random(DateTime.Now.Millisecond).Next(9999);
// Use DataTableMapping to map the source tables and the destination tables.
DataTableMapping[] tableMappings = {new DataTableMapping("Table", "Department"), new DataTableMapping("Table1", "Course")};
CopyData(mySchool, settings.MySchoolConnectionString, selectCommand, tableMappings);
Console.WriteLine("The following tables are from the database.");
foreach (DataTable table in mySchool.Tables) {
Console.WriteLine(table.TableName);
ShowDataTable(table);
}
// Roll back the changes
DataTable department = mySchool.Tables["Department"];
DataTable course = mySchool.Tables["Course"];
department.Rows[0]["Name"] = "New" + department.Rows[0][1];
course.Rows[0]["Title"] = "New" + course.Rows[0]["Title"];
course.Rows[0]["Credits"] = 10;
Console.WriteLine("After we changed the tables:");
foreach (DataTable table in mySchool.Tables) {
Console.WriteLine(table.TableName);
ShowDataTable(table);
}
department.RejectChanges();
Console.WriteLine("After use the RejectChanges method in Department table to roll back the changes:");
ShowDataTable(department);
DataColumn[] primaryColumns = { course.Columns["CourseID"] };
DataColumn[] resetColumns = { course.Columns["Title"] };
ResetCourse(course, settings.MySchoolConnectionString, primaryColumns, resetColumns);
Console.WriteLine("After use the ResetCourse method in Course table to roll back the changes:");
ShowDataTable(course);
// Batch update the table.
String insertString = @"Insert into [MySchool].[dbo].[Course]([CourseID],[Year],[Title],
[Credits],[DepartmentID])
values (@CourseID,@Year,@Title,@Credits,@DepartmentID)";
SqlCommand insertCommand = new SqlCommand(insertString);
insertCommand.Parameters.Add("@CourseID", SqlDbType.NVarChar, 10, "CourseID");
insertCommand.Parameters.Add("@Year", SqlDbType.SmallInt, 2, "Year");
insertCommand.Parameters.Add("@Title", SqlDbType.NVarChar, 100, "Title");
insertCommand.Parameters.Add("@Credits", SqlDbType.Int, 4, "Credits");
insertCommand.Parameters.Add("@DepartmentID", SqlDbType.Int, 4, "DepartmentID");
const Int32 batchSize = 10;
BatchInsertUpdate(course, settings.MySchoolConnectionString, insertCommand, batchSize);
}
private static void CopyData(DataSet dataSet, String connectionString, SqlCommand selectCommand, DataTableMapping[] tableMappings) {
using (SqlConnection connection = new SqlConnection(connectionString)) {
selectCommand.Connection = connection;
connection.Open();
using (SqlDataAdapter adapter = new SqlDataAdapter(selectCommand)) {adapter.TableMappings.AddRange(tableMappings);
// If set the AcceptChangesDuringFill as the false, AcceptChanges will not be called on a
// DataRow after it is added to the DataTable during any of the Fill operations.
adapter.AcceptChangesDuringFill = false;
adapter.Fill(dataSet);
}
}
}
// Roll back only one column or several columns data of the Course table by call ResetDataTable method.
private static void ResetCourse(DataTable table, String connectionString,
DataColumn[] primaryColumns, DataColumn[] resetColumns) {
table.PrimaryKey = primaryColumns;
// Build the query string
String primaryCols = String.Join(",", primaryColumns.Select(col => col.ColumnName));
String resetCols = String.Join(",", resetColumns.Select(col => $"Max({col.ColumnName}) as {col.ColumnName}"));
String selectString = $"Select {primaryCols},{resetCols} from Course Group by {primaryCols}");
SqlCommand selectCommand = new SqlCommand(selectString);
ResetDataTable(table, connectionString, selectCommand);
}
// RejectChanges will roll back all changes made to the table since it was loaded, or the last time AcceptChanges
// was called. When you copy from the database, you can lose all the data after calling RejectChanges
// The ResetDataTable method rolls back one or more columns of data.
private static void ResetDataTable(DataTable table, String connectionString,
SqlCommand selectCommand) {
using (SqlConnection connection = new SqlConnection(connectionString)) {
selectCommand.Connection = connection;
connection.Open();
using (SqlDataAdapter adapter = new SqlDataAdapter(selectCommand)) {
// The incoming values for this row will be written to the current version of each
// column. The original version of each column's data will not be changed.
adapter.FillLoadOption = LoadOption.Upsert;
adapter.Fill(table);
}
}
}
private static void BatchInsertUpdate(DataTable table, String connectionString,
SqlCommand insertCommand, Int32 batchSize) {
using (SqlConnection connection = new SqlConnection(connectionString)) {
insertCommand.Connection = connection;
// When setting UpdateBatchSize to a value other than 1, all the commands
// associated with the SqlDataAdapter have to have their UpdatedRowSource
// property set to None or OutputParameters. An exception is thrown otherwise.
insertCommand.UpdatedRowSource = UpdateRowSource.None;
connection.Open();
using (SqlDataAdapter adapter = new SqlDataAdapter()) {
adapter.InsertCommand = insertCommand;
// Gets or sets the number of rows that are processed in each round-trip to the server.
// Setting it to 1 disables batch updates, as rows are sent one at a time.
adapter.UpdateBatchSize = batchSize;
adapter.Update(table);
Console.WriteLine("Successfully to update the table.");
}
}
}
private static void ShowDataTable(DataTable table) {
foreach (DataColumn col in table.Columns) {
Console.Write("{0,-14}", col.ColumnName);
}
Console.WriteLine("{0,-14}", "RowState");
foreach (DataRow row in table.Rows) {
foreach (DataColumn col in table.Columns) {
if (col.DataType.Equals(typeof(DateTime)))
Console.Write("{0,-14:d}", row[col]);
else if (col.DataType.Equals(typeof(Decimal)))
Console.Write("{0,-14:C}", row[col]);
else
Console.Write("{0,-14}", row[col]);
}
Console.WriteLine("{0,-14}", row.RowState);
}
}
}