Veri Kaynaklarını DataAdapters ile Güncelleştirme

Update yöntemiDataAdapter, geriden DataSet veri kaynağına yapılan değişiklikleri çözmek için çağrılır. Update yöntemi gibi Fill yöntemi, bağımsız değişken olarak bir örneği DataSetve isteğe bağlı DataTable bir nesne veya DataTable ad alır. Örnek DataSet , yapılan değişiklikleri içeren örnektir DataSet ve DataTable değişikliklerin alındığı tabloyu tanımlar. BelirtilmezseDataTable, içindeki DataSet ilk DataTable kullanılır.

yöntemini çağırdığınızda Update , DataAdapter yöntemi yapılan değişiklikleri analiz eder ve uygun komutu yürütür (INSERT, UPDATE veya DELETE). bir değişiklikle karşılaştığındaDataAdapter, değişikliği işlemek için , UpdateCommandveya DeleteCommand kullanırInsertCommand.DataRow Bu, ADO.NET uygulamanızın performansını en üst düzeye çıkarmak için tasarım zamanında ve mümkün olduğunda saklı yordamlar kullanarak komut söz dizimini belirtmenizi sağlar. komutunu çağırmadan Updateönce komutları açıkça ayarlamanız gerekir. çağrılırsa Update ve belirli bir güncelleştirme için uygun komut yoksa (örneğin, silinen satırlar için hayır DeleteCommand ), bir özel durum oluşturulur.

Not

kullanarak verileri DataAdapterdüzenlemek veya silmek için SQL Server saklı yordamları kullanıyorsanız saklı yordam tanımında SET NOCOUNT ON kullanmadığınızdan emin olun. Bu, etkilenen satır sayısının sıfır olmasına neden olur ve bu DataAdapter da eşzamanlılık çakışması olarak yorumlar. Bu olayda bir DBConcurrencyException oluşturulur.

Komut parametreleri, bir SQL deyiminin giriş ve çıkış değerlerini veya bir içindeki DataSetdeğiştirilen her satır için saklı yordam belirtmek için kullanılabilir. Daha fazla bilgi için bkz . DataAdapter Parametreleri.

Not

Bir satır silme ile satırı DataTable kaldırma arasındaki farkı anlamak önemlidir. veya RemoveAt yöntemini çağırdığınızdaRemove, satır hemen kaldırılır. Arka uç veri kaynağındaki karşılık gelen satırlar, veya DataSet öğesini bir ve çağrısına UpdateDataAdapter geçirirseniz DataTable etkilenmez. yöntemini kullandığınızda Delete , satır içinde DataTable kalır ve silinmek üzere işaretlenir. Ardından veya DataSetDataAdapter ve DataTable çağrısı Updategeçirirseniz, arka uç veri kaynağındaki karşılık gelen satır silinir.

ile DataTable eşleniyorsa veya tek bir veritabanı tablosundan oluşturulduysa, nesnesinden DbCommandBuilder yararlanarak için DataAdapter, InsertCommandve UpdateCommand nesnelerini otomatik olarak oluşturabilirsinizDeleteCommand. Daha fazla bilgi için bkz . CommandBuilders ile Komut Oluşturma.

Değerleri Bir DataSet ile Eşlemek için UpdatedRowSource Kullanma

Bir nesnenin özelliğini DbCommand kullanarak veri kaynağından döndürülen değerlerin bir öğesinin Update yöntemine DataAdapteryapılan aşağıdaki çağrıya UpdatedRowSource nasıl eşlenebileceğini DataTable denetleyebilirsiniz. özelliğini numaralandırma değerlerinden birine ayarlayarakUpdatedRowSource, komutlar tarafından döndürülen çıkış parametrelerinin DataAdapter yok sayılıp yoksayılmayacağını veya içindeki DataSetdeğiştirilen satıra uygulanıp uygulanmayacağını denetleyebilirsiniz.UpdateRowSource Ayrıca, döndürülen ilk satırın (varsa) içindeki DataTabledeğiştirilen satıra uygulanıp uygulanmayacağını da belirtebilirsiniz.

Aşağıdaki tabloda, numaralandırmanın farklı değerleri UpdateRowSource ve ile DataAdapterkullanılan bir komutun davranışını nasıl etkilediği açıklanmaktadır.

UpdatedRowSource Numaralandırması Açıklama
Both Hem çıkış parametreleri hem de döndürülen sonuç kümesinin ilk satırı içindeki DataSetdeğiştirilen satıra eşlenebilir.
FirstReturnedRecord Yalnızca döndürülen sonuç kümesinin ilk satırındaki veriler içindeki DataSetdeğiştirilen satıra eşlenebilir.
None Döndürülen sonuç kümesinin çıkış parametreleri veya satırları yoksayılır.
OutputParameters Yalnızca çıkış parametreleri içindeki DataSetdeğiştirilen satıra eşlenebilir.

Update yöntemi, veri kaynağındaki değişikliklerinizi çözer; ancak diğer istemciler son doldurduğunuzdan bu yana veri kaynağındaki DataSetverileri değiştirmiş olabilir. Geçerli verilerle yenilemek DataSet için ve Fill yöntemini kullanınDataAdapter. Tabloya yeni satırlar eklenir ve güncelleştirilmiş bilgiler mevcut satırlara eklenir. yöntemi, Fill içindeki ve tarafından SelectCommanddöndürülen satırların birincil anahtar değerlerini inceleyerek yeni satır eklenip eklenmeyeceğini veya mevcut bir satırın DataSet güncelleştirilip güncelleştirilmeyeceğini belirler. yöntemi, Fill tarafından döndürülen SelectCommandsonuçlardaki DataSet bir satırdaki birincil anahtar değeriyle eşleşen bir satır için birincil anahtar değeriyle karşılaşırsa, var olan satırı tarafından döndürülen SelectCommand satırdaki bilgilerle güncelleştirir ve var olan satırın değerini olarak UnchangedayarlarRowState. tarafından döndürülen bir satır, SelectCommand içindeki satırların DataSetFill birincil anahtar değerlerinden hiçbiriyle eşleşmeyen bir birincil anahtar değerine sahipse, yöntemi ile RowStateUnchangedyeni bir satır ekler.

Not

SelectCommand bir OUTER JOIN sonucunu döndürürse, DataAdapter sonucu DataTableiçin bir PrimaryKey değer ayarlamaz. Yinelenen satırların PrimaryKey doğru çözümlenmesi için kendinizi tanımlamanız gerekir. Daha fazla bilgi için bkz . Birincil Anahtarları Tanımlama.

yöntemini çağırırken Update oluşabilecek özel durumları işlemek için, olayı kullanarak RowUpdated satır güncelleştirme hatalarını oluştukları sırada yanıtlayabilirsiniz (bkz. DataAdapter Olaylarını İşleme) veya çağrısından Updateönce olarak ayarlayabilir DataAdapter.ContinueUpdateOnErrortrue ve güncelleştirme tamamlandığında belirli bir satırın özelliğinde RowError depolanan hata bilgilerini yanıtlayabilirsiniz (bkz. Satır Hata Bilgileri).

Not

, veya üzerinde DataSetçağrılmasıAcceptChanges, için DataRow tüm Original değerlerin üzerine yazılmasını ve değerlerinin Current yazılmasını DataRowDataRow sağlar. DataTable Satırı benzersiz olarak tanımlayan alan değerleri değiştirilmişse, değerler çağrıldıktan AcceptChangesOriginal sonra veri kaynağındaki değerlerle eşleşmez. AcceptChanges , bir öğesinin Update yöntemine yapılan çağrı sırasında her satır için otomatik olarak çağrılır DataAdapter. Önce özelliğini DataAdapter false olarak ayarlayarak AcceptChangesDuringUpdate veya olay için RowUpdated bir olay işleyicisi oluşturup olarak ayarlayarak StatusSkipCurrentRowUpdate yöntemine yapılan bir çağrı sırasında özgün değerleri koruyabilirsiniz. Daha fazla bilgi için bkz . DataSet İçeriğini Birleştirme ve DataAdapter Olaylarını İşleme.

Örnek

Aşağıdaki örneklerde, öğesini açıkça ayarlayarak UpdateCommand ve yöntemini çağırarak değiştirilen satırlarda güncelleştirmelerin DataAdapter nasıl gerçekleştirildiği gösterilmektedir Update . UPDATE deyiminin WHERE yan tümcesinde belirtilen parametrenin değerini kullanacak Original şekilde ayarlandığına SourceColumndikkat edin. Bu önemlidir çünkü Current değer değiştirilmiş olabilir ve veri kaynağındaki değerle eşleşmeyebilir. Original değeri, veri kaynağından öğesini doldurmak DataTable için kullanılan değerdir.

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

OtomatikCrement Sütunları

Veri kaynağınızdaki tablolarda DataSet otomatik artan sütunlar varsa, saklı yordamın çıkış parametresi olarak otomatik artırma değerini döndürerek ve bunu tablodaki bir sütuna eşleyerek, saklı yordam veya SQL deyimi tarafından döndürülen sonuç kümesinin ilk satırındaki otomatik artış değerini döndürerek sütunları doldurabilirsiniz. veya ek bir SELECT deyimi yürütmek için öğesinin DataAdapter olayını kullanarakRowUpdated. Daha fazla bilgi ve örnek için bkz . Kimlik veya Otomatik Sayı Değerlerini Alma.

Eklemeler, Güncelleştirmeler ve Silmelerin Sıralanması

Çoğu durumda, aracılığıyla DataSet yapılan değişikliklerin veri kaynağına gönderilme sırası önemlidir. Örneğin, var olan bir satır için birincil anahtar değeri güncelleştirilir ve yeni birincil anahtar değeri yabancı anahtar olarak yeni bir satır eklenirse, ekleme işleminden önce güncelleştirmeyi işlemek önemlidir.

yalnızca belirli RowStatebir ile satırlara başvuran bir DataRow dizi döndürmek için yöntemini DataTable kullanabilirsinizSelect. Daha sonra döndürülen DataRow diziyi Update yöntemine DataAdapter geçirerek değiştirilen satırları işleyebilirsiniz. Güncelleştirilecek satırların bir alt kümesini belirterek, eklemelerin, güncelleştirmelerin ve silmelerin işlenme sırasını denetleyebilirsiniz.

Örneğin, aşağıdaki kod önce tablonun silinen satırlarının, ardından güncelleştirilmiş satırların ve ardından eklenen satırların işlenmesini sağlar.

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));

Veri Almak ve Güncelleştirmek için DataAdapter Kullanma

Verileri almak ve güncelleştirmek için DataAdapter kullanabilirsiniz.

  • Örnek, veritabanındaki verileri kopyalamak için DataAdapter.AcceptChangesDuringFill kullanır. Özellik false olarak ayarlanırsa, tablo doldurulurken AcceptChanges çağrılmaz ve yeni eklenen satırlar eklenen satırlar olarak kabul edilir. Bu nedenle örnek, yeni satırları veritabanına eklemek için bu satırları kullanır.

  • Örneklerde, kaynak tablo ile DataTable arasındaki eşlemeyi tanımlamak için DataAdapter.TableMappings kullanılır.

  • Örnek, bağdaştırıcının DbDataReader'dan DataTable'ı nasıl doldurduğunu belirlemek için DataAdapter.FillLoadOption kullanır. DataTable oluşturduğunuzda, yalnızca özelliği LoadOption.Upsert veya LoadOption.PreserveChanges olarak ayarlayarak veritabanından geçerli sürüme veya özgün sürüme veri yazabilirsiniz.

  • Örnek ayrıca toplu işlem gerçekleştirmek için DbDataAdapter.UpdateBatchSize kullanarak tabloyu güncelleştirir.

Örneği derleyip çalıştırmadan önce örnek veritabanını oluşturmanız gerekir:

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()]
      [global::System.Configuration.DefaultSettingValueAttribute("Data Source=(local);Initial Catalog=MySchool;Integrated Security=True")]
      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);
      }
   }
}

Ayrıca bkz.