TGViewer
C# Geeks (.NET) C# Geeks (.NET) @csharpgeeks · 550 subscribers
Post #481 187
🚀 Fast SQL Bulk Inserts With C# and EF Core

فرقی نمی‌کند دارید یک پلتفرم تحلیل داده می‌سازید، یک سیستم قدیمی را مهاجرت می‌دهید، یا یک موج بزرگ از کاربران جدید وارد سیستم‌تان می‌شوند—به‌احتمال زیاد زمانی می‌رسد که باید مقدار عظیمی داده را وارد دیتابیس کنید.

وارد کردن رکوردها یکی‌یکی مثل این است که خشک‌شدن رنگ را در حرکت آهسته تماشا کنید! روش‌های سنتی اصلاً جواب نمی‌دهند.
پس یاد گرفتن تکنیک‌های bulk insert سریع با #C و EF Core تبدیل به یک مهارت ضروری می‌شود.

در این مقاله، چندین روش برای انجام bulk insert در #C بررسی می‌کنیم:
• Dapper
• EF Core
• EF Core Bulk extensions
• SQL Bulk Copy
• Entity Framework Extensions

تمام مثال‌ها بر اساس یک کلاس User و جدول Users در SQL Server هستند:
public class User
{
public int Id { get; set; }
public string Email { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string PhoneNumber { get; set; }
}

این لیست کامل تمام روش‌های bulk insert نیست. چند گزینه دیگر بررسی نشده‌اند، مثل تولید دستی SQL یا استفاده از Table-Valued parameters.

📌EF Core Simple Approach

بیایید با یک مثال ساده با EF Core شروع کنیم. ما یک ApplicationDbContext می‌سازیم، یک شی User اضافه می‌کنیم و SaveChangesAsync را صدا می‌زنیم. این کار باعث می‌شود هر رکورد به‌صورت جداگانه در دیتابیس insert شود. یعنی برای هر رکورد یک round trip به دیتابیس نیاز داریم.
using var context = new ApplicationDbContext();

foreach (var user in GetUsers())
{
context.Users.Add(user);

await context.SaveChangesAsync();
}

و نتایج دقیقاً همان‌قدر ضعیف هستند که انتظار دارید:
EF Core - Add one and save برای 100 کاربر: 20 ms

EF Core - Add one and save برای 1,000 کاربر: 260 ms

EF Core - Add one and save برای 10,000 کاربر: 8,860 ms

نتایج 100,000 و 1,000,000 رکورد حذف شدند چون اجرای آنها بیش از حد طولانی شد.

این مثال را به‌عنوان «چگونه bulk insert انجام ندهیم» در نظر بگیرید.

🧩Dapper Simple Insert

Dapper
یک SQL-to-object mapper ساده برای NET. است. این ابزار اجازه می‌دهد مجموعه‌ای از اشیا را به‌راحتی در دیتابیس insert کنیم.

من از قابلیت Dapper برای unwrap کردن یک collection داخل یک SQL INSERT statement استفاده می‌کنم.
using var connection = new SqlConnection(connectionString);
connection.Open();

const string sql =
@"
INSERT INTO Users (Email, FirstName, LastName, PhoneNumber)
VALUES (@Email, @FirstName, @LastName, @PhoneNumber);
";

await connection.ExecuteAsync(sql, GetUsers());

نتایج بسیار بهتر از مثال ابتدایی هستند:
Dapper - Insert range برای 100 کاربر: 10 ms

Dapper - Insert range برای 1,000 کاربر: 113 ms

Dapper - Insert range برای 10,000 کاربر: 1,028 ms

Dapper - Insert range برای 100,000 کاربر: 10,916 ms

Dapper - Insert range برای 1,000,000 کاربر: 109,065 ms


🔸️EF Core Add and Save

اما EF Core هم هنوز کنار نکشیده. مثال اول عمداً خیلی ضعیف پیاده‌سازی شده بود. EF Core می‌تواند چندین SQL statement را با هم batch کند، پس از این قابلیت استفاده می‌کنیم.

اگر یک تغییر ساده بدهیم، می‌توانیم عملکرد به‌مراتب بهتری بگیریم. اول، همهٔ اشیا را به ApplicationDbContext اضافه می‌کنیم. سپس فقط یک‌بار SaveChangesAsync را صدا می‌زنیم.

این EF یک batched SQL statement می‌سازد—یعنی چندین INSERT را با هم گروه می‌کند—و همه را یکجا به دیتابیس می‌فرستد. این کار تعداد round trip ها را کم می‌کند و باعث بهبود سرعت می‌شود.
using var context = new ApplicationDbContext();

foreach (var user in GetUsers())
{
context.Users.Add(user);
}

await context.SaveChangesAsync();

نتایج benchmark این پیاده‌سازی:
EF Core - Add all and save برای 100 کاربر: 2 ms

EF Core - Add all and save برای 1,000 کاربر: 18 ms

EF Core - Add all and save برای 10,000 کاربر: 203 ms

EF Core - Add all and save برای 100,000 کاربر: 2,129 ms

EF Core - Add all and save برای 1,000,000 کاربر: 21,557 ms

به یاد داشته باشید: Dapper برای insert کردن 1,000,000 رکورد حدود 109 ثانیه زمان گرفت. با EF Core و batched queries، همان کار را در حدود 21 ثانیه انجام می‌دهیم.
More from @csharpgeeks
  1. Sep 22, 2026یه مدتی قراره از دنیای NET. فاصله بگیرم، چون وقتشه برم سربازی. راستش نمیدونم این مدت رو چج…
  2. Sep 20, 2026🔥 حالا مشکل اصلی: Alert Storm فرض کن Database از دسترس خارج شده. ۱۰۰ Pod داری. هر Pod می‌…
  3. Sep 20, 2026🚨 طراحی سیستم Monitoring و Alerting در یک سیستم بزرگ فرض کن ساعت ۳ صبح است. سیستم شما با…
  4. Sep 19, 2026#Engineering_Leadership تصمیم نگرفتن هم یک تصمیم است یه چیز عجیب توی تیم‌های مهندسی: گاهی…
  5. Sep 19, 2026☑ چک‌لیست آماده‌سازی تیم، فرایندها و زیرساخت برای توسعه با AI توجه: هیچ چک‌لیستی جهان‌شمول…
  6. Sep 19, 2026📌پایان یک انتظار طولانی: اعتبارسنجی ناهمگام (Async Validation) در NET 11.
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →