في .Net1.1، ليس من المناسب جدًا إدراج كافة البيانات الموجودة في DataTable بالكامل في قاعدة البيانات أو الترحيل بين مصادر البيانات المختلفة. في .Net2.0، تمت إضافة عدة فئات جديدة ضمن مساحة اسم SQLClient لمساعدتنا في ترحيل البيانات على دفعات من خلال DataTable أو DataReader. يمكن أن يأتي مصدر البيانات من قاعدة بيانات علائقية أو ملف XML، أو حتى النتائج التي يتم إرجاعها بواسطة WebService. واحدة من أهم الفئات هي فئة SqlBulkCopy، والتي يمكن أن تساعدنا بسهولة في ترحيل البيانات من مصدر البيانات إلى قاعدة البيانات الهدف.
دعونا أولا نوضح استخدام هذا الصنف من خلال مثال بسيط:
التاريخ والوقت startTime؛
باطلة محمية Button1_Click(مرسل الكائن، EventArgs e)
{
startTime = DateTime.Now;
سلسلة سركونسترينغ؛
سلسلة DesConString؛
SqlConnection SrcCon = new SqlConnection();
SqlConnection DesCon = new SqlConnection();
SqlCommand SrcCom = new SqlCommand();
SqlDataAdapter SrcAdapter = new SqlDataAdapter();
DataTable dt = new DataTable();
سركونسترينغ =
ConfigurationManager.ConnectionStrings["SrcDBConnectionString"].ConnectionString;
ديكونسترينغ =
ConfigurationManager.ConnectionStrings["DesDBConnectionString"].ConnectionString;
SrcCon.ConnectionString = SrcConString;
SrcCom.Connection = SrcCon;
SrcCom.CommandText = " SELECT * From [SrcTable]";
SrcCom.CommandType = CommandType.Text;
SrcCom.Connection.Open();
SrcAdapter.SelectCommand = SrcCom;
SrcAdapter.Fill(dt);
SqlBulkCopy DesBulkOp;
DesBulkOp = SqlBulkCopy الجديد (DesConString،
SqlBulkCopyOptions.UseInternalTransaction);
DesBulkOp.BulkCopyTimeout = 500000000;
DesBulkOp.SqlRowsCopied +=
new SqlRowsCopiedEventHandler(OnRowsCopied);
DesBulkOp.NotifyAfter = dt.Rows.Count;
يحاول
{
DesBulkOp.DestinationTableName = "SrcTable";
DesBulkOp.WriteToServer(dt);
}
قبض (استثناء على سبيل المثال)
{
lblResult.Text = ex.Message;
}
أخيراً
{
SrcCon.Close();
DesCon.Close();
}
}
OnRowsCopied باطلة خاصة (مرسل الكائن، SqlRowsCopiedEventArgs args)
{
lblCounter.Text += args.RowsCopied.ToString() + "تم نسخ الصفوف<Br>";
TimeSpan CopyTime = DateTime.Now - startTime;
lblCounter.Text += "وقت النسخ:" + CopyTime.Seconds.ToString() + "." + CopyTime.Millithans.ToString() + " ثواني";
}
ثم قم بتحليل سطور التعليمات البرمجية هذه بالتفصيل:
SqlBulkCopy DesBulkOp;
DesBulkOp = new SqlBulkCopy(DesConString, SqlBulkCopyOptions.UseInternalTransaction); أولاً، قم بإنشاء مثيل SqlBulkCopy يحدد المنشئ قاعدة البيانات الهدف. استخدام SqlBulkCopyOptions.UseInternalTransaction يعني أنه تم تحديد إجراء الترحيل في معاملة. سيحدث التراجع. يرجى الرجوع إلى MSDN للحصول على خيارات أخرى.
DesBulkOp.BulkCopyTimeout = 500000000;
حدد وقت المهلة لإكمال العملية
DesBulkOp.SqlRowsCopied += new SqlRowsCopiedEventHandler(OnRowsCopied);
DesBulkOp.NotifyAfter = dt.Rows.Count;
يحاول
{
DesBulkOp.DestinationTableName = "SrcTable";
DesBulkOp.WriteToServer(dt);
}
تحدد سمة NotifyAfter عدد صفوف البيانات التي ستتم معالجتها قبل حدث الإعلام، ويتم تحديدها هنا على أنها عدد الصفوف في الجدول، ويتم إضافة حدث SqlRowsCopied لإخراج وقت عملية الترحيل بأكملها. يقوم أسلوب WriteToServer بنسخ مصدر البيانات إلى قاعدة البيانات الهدف. قبل استخدام طريقة WriteToServer، يجب عليك أولاً تحديد سمة DestinationTableName، وهي اسم جدول قاعدة البيانات الهدف،
ويمكننا أيضًا تحديد المعاملة بأنفسنا، على سبيل المثال:
SqlTransaction Transaction؛
الصفقة =
SrcCom.Connection.BeginTransaction();
SqlBulkCopy DesBulkOp;
DesBulkOp = new SqlBulkCopy(new SqlConnection(DesConString),
سقلبولككوبيوبتيونس.افتراضي،
الصفقة)؛
حاول
{
//..
}
يمسك{}
أخيراً
{
Transaction.Commit();
}
هناك أيضًا فئة SqlBulkCopyColumnMapping التي تسمح بتعيين حقول مصدر البيانات إلى حقول ذات أسماء مختلفة في البيانات الهدف. وهذا يعني أنه إذا كانت أسماء أعمدة البيانات الهدف وبيانات المصدر مختلفة، فيمكنك استخدام هذه الفئة لرسم الخرائط:
SqlBulkCopyColumnMapping ColMap = new SqlBulkCopyColumnMapping("SrcCol", "DesCol");
DesBulkOp.ColumnMappings.Add(ColMap);
أو يمكنك إضافة الخرائط مباشرة:
DesBulkOp.ColumnMappings.Add("SrcCol", "DesCol");
قضايا الأداء:
لقد استخدمت المثال أعلاه لاختبار وترحيل حوالي 20000 سجل، وقد استغرق الأمر أقل من ثانية واحدة، ويجب أن أقول إن الأداء لا يزال جيدًا. بالإضافة إلى ذلك، باستخدام ملف تعريف SQL لمراقبة أحداث الترحيل، يمكنك أن ترى أن هناك عددًا قليلاً جدًا من سجلات الطلبات، عدد قليل فقط. يقال أن استخدام SqlBulkCopy يمكن أن يقلل بشكل كبير من وقت ترحيل البيانات.