EFCore.BulkExtensions 批量資料處理

大量資料需要處理的時候,都會想到Bulk Inset(T-SQL)這個指令,
EFCore時代中有沒有類似的功能,效能又是如何呢?

介紹EFCore.BulkExtensions,是建立在.Net Core時期的而非.Net Framework時期(也有,但要收費)

實驗一下EF Core中慣用的AddRange與BulkInsert效能差異

程式碼

class Program
    {
        private static Logger Logger = NLogBuilder.ConfigureNLog("nlog.config").GetCurrentClassLogger();
        static void Main(string[] args)
        {
            Logger.Info("Start");
            Save(1000);
            Save(3000);
            Save(5000);
            Save(10000);
            Save(100000);
            CloseSave(1000);
            CloseSave(3000);
            CloseSave(5000);
            CloseSave(10000);
            CloseSave(100000);
            Logger.Info("End");
        }
        private static void Save(int i)
        {
            using (var db = new TestContext())
            {
                List<Test_table> list = new List<Test_table>();
                for (int k = 0; k < i; k++)
                {
                    list.Add(new Test_table { num = k, message = $"{i} 筆數 準備寫入" });
                }
                db.Test_table.AddRange(list);
                Logger.Info($"{i} 筆數 準備寫入");
                db.SaveChanges();
                Logger.Info($"{i} 筆數 寫入結束");
            }
        }
        private static void CloseSave(int i)
        {
            using (var db = new TestContext())
            {
                List<Test_table> list = new List<Test_table>();
                for (int k = 0; k < i; k++)
                {
                    list.Add(new Test_table { num = k, message = $"{i} 筆數 BulkInsert準備寫入" });
                }
                Logger.Info($"BulkInsert");
                Logger.Info($"{i} 筆數 準備寫入");
                db.BulkInsert(list);
                Logger.Info($"{i} 筆數 寫入結束");
            }
        }

    }

實驗用的資料表

測試結果

數據圖

從圖中可以觀察到,1000筆的數據有些不明的效能影響,
從3000筆後的數據可以看出,當超過千筆以上,且有效能考量,不建議使用AddRange
例如BeginTransaction鎖定資料表,產生deadlock