在 Entity Framework 核心 6 中一次插入多条记录

Inserting multiple records at once in Entity Framework Core 6

我正在使用 .NET Core 6 minimal api 和 PostgreSQL 13 数据库。我使用的软件包是 Microsoft.EntityFrameworkCore 6.0.0 和 Npgsql.EntityFrameworkCore.PostgreSQL。我将内容设置为 LogLevel.Information 以便我可以查看 SQL 查询 Entity Framework Core 在与数据库对话时创建的查询。

我注意到,当我通过端点插入记录时,它会执行一系列单个插入语句,而不是预期的 (VALUES (<row1 values>),(<row2 values>)) 格式。例如,它正在记录:

INSERT INTO <mytable> (<columns>) VALUES (<row1 values>);
INSERT INTO <mytable> (<columns>) VALUES (<row2 values>);

这是我的插入代码:

context.Items.AddRange(list);
await context.SaveChangesAsync();

有没有办法将所有值合并到一个 INSERT 查询中?

这就是 EF 的工作原理。没有 Change Tracker,您将无法 insert/update/delete 任何事情。如果有很多记录,则性能不佳。 PostgreSQL 有 COPY 用于插入大量记录,如果您担心性能,您可以使用 Npgsql 提供的这种能力。

虽然有一种快速插入记录的方法,但它是非常低级的机制,需要大量的努力和准确的映射才能使其工作。

所以,有很多 EF Core 扩展可以让它以最小的努力工作。其中之一是 linq2db.EntityFrameworkCore,请注意,我是创作者之一,我的意见可能是主观的。

安装库后,您只需调用BulkCopy即可插入一批记录。

await context.BulkCopyAsync(items);

还有调整参数可以提高性能。

@svyatoslav-danyliv 回答不准确。

EF Core 全部批处理 inserts/updates:当您在 DbContext 上执行 SaveChanges 时,所有累积的更改都通过单个命令在单个往返中发送(您可以使用数据包嗅探器,例如 wireshark观察这个)。

请注意,在某些情况下,这可能比单个 INSERT 查询 高效,因为多个 INSERT 语句是参数化的并且具有相同的 SQL,所以相同预处理语句可以重复使用。

话虽如此,如果您要批量导入大量记录,使用 Npgsql 的低级 COPY 支持可能仍然值得。我强烈建议使用 BenchmarkDotNet 编写一个快速基准测试,并将各种解决方案与您自己的场景进行比较。