日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

EFCore批量操作,你真的清楚吗

發布時間:2023/12/4 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 EFCore批量操作,你真的清楚吗 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

背景

EntityFramework Core有許多新的特性,其中一個重要特性便是批量操作。批量操作意味著不需要為每次Insert/Update/Delete操作發送單獨的命令,而是在一次SQL請求中發送批量組合指令。

EFCore批量操作實踐

批處理是期待已久的功能,社區多次提出要求。現在EFCore支持開箱即用確實很棒,可以提高應用程序的性能和速度。

1

對比實踐

以常見的批量插入為例,使用SQL Server Profiler觀察產生并執行的SQL語句。

//?category表添加3條記錄并執行保存
using?(var?c=?new?SampleDBContext())
{
????c.Categories.Add(new?Category()?{?CategoryID?=?1,?CategoryName?=?"Clothing"?});
????c.Categories.Add(new?Category()?{?CategoryID?=?2,?CategoryName?=?"Footwear"?});
????c.Categories.Add(new?Category()?{?CategoryID?=?3,?CategoryName?=?"Accessories"?});
????c.SaveChanges();
}

當執行SaveChanges(), 從SQL Profiler追溯到的SQL:

exec?sp_executesql?N'SET?NOCOUNT?ON;INSERT?INTO?[Categories]?([CategoryID],?[CategoryName])
VALUES?(@p0,?@p1),(@p2,?@p3),(@p4,?@p5);',N'@p0?int,@p1?nvarchar(4000),@p2?int,@p3?nvarchar(4000),@p4?int,@p5?nvarchar(4000)',
@p0=1,@p1=N'Clothing',@p2=2,@p3=N'Footwear',@p4=3,@p5=N'Accessories'

如你所見,批量插入沒有產生3個獨立的語句,而是被組合為一個傳參存儲過程腳本(用列值作為參數);如果使用EF6執行相同的代碼,則在SQL Server Profiler中將看到3個獨立的插入語句 。下面是EFCore、EF6批量插入的對比截圖:

① 就性能和速度而言,EFCore批量插入更具優勢

② 若數據庫是針對云部署,EF6運行這些查詢,還將產生額外的流量成本

經過驗證:EFCore批量更新、批量刪除功能,EFCore均發出了使用sp_executesql存儲過程+批量參數構建的SQL腳本。

2

深入分析

起關鍵作用的存儲過程sp_executesql:可以多次執行的語句或批處理 (可帶參)

-?Syntax?for?SQL?Server,?Azure?SQL?Database,?Azure?SQL?Data?Warehouse,?Parallel?Data?Warehouse??
??
sp_executesql?[?@stmt?=?]?statement??
[???
??{?,?[?@params?=?]?N'@parameter_name?data_type?[?OUT?|?OUTPUT?][?,...n?]'?}???
?????{?,?[?@param1?=?]?'value1'?[?,...n?]?}??
]

注意官方限制:

The amount of data that can be passed by using this method is limited by the number of parameters allowed. SQL Server procedures can have, at most, 2100 parameters. Server-side logic is required to assemble these individual values into a table variable or a temporary table for processing.??? ? ?// SQL存儲過程最多可使用2100個參數

3

豁然開朗

SqlServer sp_executesql存儲過程最多支持2100個批量操作形成的列值參數,所以遇到很大數量的批量操作,EFCore SqlProvider會幫我們將批量操作分塊傳輸,這也是我們在實際大批量使用時看到分塊發送的原因。

EFCore開放了【配置關系型數據庫批量操作大小】:

protected?override?void?OnConfiguring(DbContextOptionsBuilder?optionbuilder)
{
????string?sConnString?=?@"Server=localhost;Database=EFSampleDB;Trusted_Connection=true;";
????optionbuilder.UseSqlServer(sConnString?,?b?=>?b.MaxBatchSize(1));?
???//?批量操作的SQL語句數量,也可設定為1禁用批量插入
}

總結


① EFCore 相比EF6,已經支持批量操作,能有效提高應用程序的性能

② EFCore的批量操作能力,由對應的DataBaseProvider支撐(Provider實現過程跟背后的存儲載體密切相關);關注SQL存儲過程sp_executesql,官方明文顯示批量操作的列值參數最多2100個,這個關鍵因素決定了在大批量操作的時候 依舊會被分塊傳輸。

③ 另外一個批量操作的方法,這里也點一下:構造Rawsql 【EFCore也支持Rawsql】

  sqlite不支持存儲過程,為批量插入提高性能,可采用此方案:


var?insertStr?=?new?StringBuilder();
insertStr.AppendLine("insert?into?ProfileUsageCounters?(profileid,datetime,quota,usage,natureusage)?values");
var?txt?=?insertStr.AppendLine(string.Join(',',?usgaeEntities.ToList().Select(x?=>
{
???????return?$"({x.ProfileId},{x.DateTime},{x.Quota},{x.Usage},{x.NatureUsage})";
}).ToArray()));
await?_context.Database.ExecuteSqlCommandAsync(txt.ToString());

+?https://github.com/aspnet/EntityFrameworkCore/issues/6604

+?https://docs.microsoft.com/en-us/dotnet/framework/data/adonet/sql/table-valued-parameters?redirectedfrom=MSDN

總結

以上是生活随笔為你收集整理的EFCore批量操作,你真的清楚吗的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。