在 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 编写一个快速基准测试,并将各种解决方案与您自己的场景进行比较。
我正在使用 .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 编写一个快速基准测试,并将各种解决方案与您自己的场景进行比较。