我正在使用。net Core 6最小api与PostgreSQL 13数据库。我使用的软件包是Microsoft.EntityFrameworkCore
6.0.0和Npgsql.EntityFrameworkCore.PostgreSQL
。我有事情将LogLevel.Information
这样我可以查看SQL查询实体框架核心谈判到数据库创建。
我注意到,当我通过端点插入记录时,它执行一系列单个插入语句,而不是预期的插入语句(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
查询中?
@svyatoslav-danyliv答案不准确
EF Core批处理所有插入/更新:当你在DbContext上执行SaveChanges时,所有累积的更改都通过单个命令发送,在单个往返中(你可以使用数据包嗅探器,如wireshark来观察这一点)。
请注意,在某些情况下,这可能比单个INSERT查询更有效率,因为多个INSERT语句是参数化的,并且具有相同的SQL,因此可以重复使用相同的预处理语句。
话虽如此,如果要批量导入大量记录,那么使用Npgsql的低级COPY支持可能仍然是值得的。我强烈建议使用BenchmarkDotNet编写一个快速基准测试,并将各种解决方案与您自己的场景进行比较。
这就是EF的工作方式。没有Change Tracker,您无法插入/更新/删除任何内容。如果有很多记录,这就不是性能了。PostgreSQL有COPY来插入大量的记录,如果你担心性能,你可以使用Npgsql提供的这种能力。
虽然有一种快速插入记录的方法,但它是一种非常底层的机制,需要大量的努力和精确的映射才能使其工作。
因此,有很多EF Core扩展可以使它以最小的努力工作。其中之一是linq2db。EntityFrameworkCore,请注意,我是创建者之一,我的意见可能是主观的。
安装库后,只需调用BulkCopy
即可插入一批记录。
await context.BulkCopyAsync(items);
还可以通过调整参数来提高性能。
更新:
对于EF Core 7,您可以使用ExecuteUpdate
和ExecuteDelete
函数,它们为Update
和Delete
提供了批量操作。