EF Core AddRange و Save ✨
این یک جایگزین برای مثال قبلی است. به جای فراخوانی Add برای همهٔ آبجکتها، میتوانیم AddRange را صدا بزنیم و یک کالکشن ارسال کنیم.
میخواستم این پیادهسازی را نشان دهم چون آن را به نمونهٔ قبلی ترجیح میدهم.
using var context = new ApplicationDbContext();
context.Users.AddRange(GetUsers());
await context.SaveChangesAsync();
نتایج بسیار مشابه نمونهٔ قبلی هستند: 📊
EF Core - Add range و Save، برای ۱۰۰ کاربر: ۲ ms
EF Core - Add range و Save، برای ۱,۰۰۰ کاربر: ۱۸ ms
EF Core - Add range و Save، برای ۱۰,۰۰۰ کاربر: ۲۰۴ ms
EF Core - Add range و Save، برای ۱۰۰,۰۰۰ کاربر: ۲,۱۱۱ ms
EF Core - Add range و Save، برای ۱,۰۰۰,۰۰۰ کاربر: ۲۱,۶۰۵ ms
EF Core Bulk Extensions ⚡️
یک کتابخانهٔ فوقالعاده به نام EF Core Bulk Extensions وجود دارد که میتوانیم برای افزایش عملکرد استفاده کنیم. شما با این کتابخانه میتوانید کارهای بیشتری از جمله bulk insert انجام دهید، بنابراین ارزش بررسی دارد. این کتابخانه متنباز است و دارای لایسنس Community میباشد اگر شرایط استفادهٔ رایگان را داشته باشید. بخش لایسنس را برای جزئیات بررسی کنید.
برای استفادهٔ ما، متد BulkInsertAsync گزینهٔ عالی است. میتوانیم کالکشن آبجکتها را ارسال کنیم و یک SQL bulk insert انجام خواهد شد.
using var context = new ApplicationDbContext();
await context.BulkInsertAsync(GetUsers());
عملکرد آن نیز شگفتانگیز است: 🚀
EF Core - Bulk Extensions، برای ۱۰۰ کاربر: ۱.۹ ms
EF Core - Bulk Extensions، برای ۱,۰۰۰ کاربر: ۸ ms
EF Core - Bulk Extensions، برای ۱۰,۰۰۰ کاربر: ۷۶ ms
EF Core - Bulk Extensions، برای ۱۰۰,۰۰۰ کاربر: ۷۴۲ ms
EF Core - Bulk Extensions، برای ۱,۰۰۰,۰۰۰ کاربر: ۸,۳۳۳ ms
برای مقایسه، ما با EF Core batched queries برای درج ۱,۰۰۰,۰۰۰ رکورد حدود ۲۱ ثانیه نیاز داشتیم. میتوانیم همان کار را با کتابخانهٔ Bulk Extensions تنها در ۸ ثانیه انجام دهیم. 😎
SQL Bulk Copy 🧩
اگر نتوانیم عملکرد دلخواه را از EF Core بگیریم، میتوانیم از SqlBulkCopy استفاده کنیم. SQL Server عملیات bulk copy را به صورت native پشتیبانی میکند، پس از آن استفاده کنیم.
این پیادهسازی کمی پیچیدهتر از مثالهای EF Core است. باید یک نمونه SqlBulkCopy را کانفیگ کنیم و یک DataTable ایجاد کنیم که شامل آبجکتهایی باشد که میخواهیم درج کنیم.
using var bulkCopy = new SqlBulkCopy(ConnectionString);
bulkCopy.DestinationTableName = "dbo.Users";
bulkCopy.ColumnMappings.Add(nameof(User.Email), "Email");
bulkCopy.ColumnMappings.Add(nameof(User.FirstName), "FirstName");
bulkCopy.ColumnMappings.Add(nameof(User.LastName), "LastName");
bulkCopy.ColumnMappings.Add(nameof(User.PhoneNumber), "PhoneNumber");
await bulkCopy.WriteToServerAsync(GetUsersDataTable());
با این حال، عملکرد فوقالعاده سریع است: 🔥
SQL Bulk Copy، برای ۱۰۰ کاربر: ۱.۷ ms
SQL Bulk Copy، برای ۱,۰۰۰ کاربر: ۷ ms
SQL Bulk Copy، برای ۱۰,۰۰۰ کاربر: ۶۸ ms
SQL Bulk Copy، برای ۱۰۰,۰۰۰ کاربر: ۶۴۶ ms
SQL Bulk Copy، برای ۱,۰۰۰,۰۰۰ کاربر: ۷,۳۳۹ ms
در ادامه نحوهٔ ایجاد DataTable و پر کردن آن با لیست آبجکتها آمده است: 🏗
DataTable GetUsersDataTable()
{
var dataTable = new DataTable();
dataTable.Columns.Add(nameof(User.Email), typeof(string));
dataTable.Columns.Add(nameof(User.FirstName), typeof(string));
dataTable.Columns.Add(nameof(User.LastName), typeof(string));
dataTable.Columns.Add(nameof(User.PhoneNumber), typeof(string));
foreach (var user in GetUsers())
{
dataTable.Rows.Add(
user.Email, user.FirstName, user.LastName, user.PhoneNumber);
}
return dataTable;
}