EF Core 高效更新

一个人走在路上發表於2024-04-03

高效更新

本文內容
批處理
在相關情況下使用 ExecuteUpdate 和 ExecuteDelete
批處理
EF Core 透過在一次往返中自動將所有更新批處理在一起,幫助最大限度地減少往返。 考慮以下情況:

C#

複製
var blog = context.Blogs.Single(b => b.Url == "http://someblog.microsoft.com");
blog.Url = "http://someotherblog.microsoft.com";
context.Add(new Blog { Url = "http://newblog1.microsoft.com" });
context.Add(new Blog { Url = "http://newblog2.microsoft.com" });
context.SaveChanges();
上述操作從資料庫載入部落格,更改其 URL,然後新增兩個新部落格;若要應用此更改,將兩個 SQL INSERT 語句和一個 UPDATE 語句傳送到資料庫。 新增部落格例項時,EF Core 不會逐個傳送,而是在內部跟蹤這些更改,並在呼叫 SaveChanges 時在單個往返中執行這些更改。

EF 在一次往返中批處理的語句數量取決於所使用的資料庫提供程式。 例如,效能分析表明,當涉及的語句少於 4 個時,批處理對於 SQL Server 的效率通常較低。 同樣,對於 SQL Server,批處理的優勢在大約 40 條語句後會降低,因此 EF Core 預設在單個批處理中最多隻執行 42 條語句,並在單獨的往返中執行額外的語句。

使用者也可以調整這些閾值以獲得潛在的更高效能,但是在修改這些閾值之前要仔細地進行基準測試:

C#

複製
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer(
@"Server=(localdb)\mssqllocaldb;Database=Blogging;Trusted_Connection=True",
o => o
.MinBatchSize(1)
.MaxBatchSize(100));
}
在相關情況下使用 ExecuteUpdate 和 ExecuteDelete
假設你想給所有員工加薪。 EF Core 中對此的典型實現如下所示:

c#

複製
foreach (var employee in context.Employees)
{
employee.Salary += 1000;
}
context.SaveChanges();
雖然這是完全有效的程式碼,但是讓我們從效能的角度來分析一下它的作用:

執行一次資料庫往返,以載入所有相關員工;請注意,這會將員工的所有行資料帶到客戶端(即使只需要工資資料)。
EF Core 的更改跟蹤在載入實體時建立快照,然後將這些快照與例項進行比較,找出哪些屬性發生了更改。
通常,執行第二個資料庫往返以儲存所有更改(請注意,某些資料庫提供程式將更改拆分為多次往返)。 儘管此批處理行為遠遠好於為每個更新執行往返,但 EF Core 仍會為每個員工傳送 UPDATE 語句,並且資料庫必須單獨執行每個語句。
從 EF Core 7.0 開始,可以使用 ExecuteUpdate 和 ExecuteDelete 方法更高效地執行相同的操作:

c#

複製
context.Employees.ExecuteUpdate(s => s.SetProperty(e => e.Salary, e => e.Salary + 1000));
這會將以下 SQL 語句傳送到資料庫:

SQL

複製
UPDATE [Employees] SET [Salary] = [Salary] + 1000;
此 UPDATE 會在單次往返中執行整個操作,而無需載入任何實際資料或將這些資料傳送到資料庫,也無需使用 EF 的更改跟蹤機制(這會增加額外的開銷)。 有關詳細資訊,請參閱 ExecuteUpdate 和 ExecuteDelete。

如果使用的是尚不支援 ExecuteUpdate 和 ExecuteDelete 的較舊版本的 EF Core,或者想要執行這些方法不支援的複雜 SQL 語句,則仍可以使用 SQL 查詢執行該操作:

EF Core 7.0
舊版本
c#

複製
context.Database.ExecuteSql($"UPDATE [Employees] SET [Salary] = [Salary] + 1000");

相關文章