如何在EF中使用一个Insert查询添加多行

时间:2014-04-23 17:22:19

标签: c# .net linq entity-framework

我有一个未知长度的字符串列表。 我将它们添加到数据库中:

if (somenteNovasClas.Any()) {
    foreach (string item in wsClassificacoes) {
        dc.Classificacaos.Add(new Classificacao { Descricao = item });
    }
    dc.SaveChanges();
}

但EF会为每一行生成一个INSERT

exec sp_executesql N'insert [dbo].[Classificacao]([Descricao], [Excluido])
values (@0, @1)
select [CodClassificacao]
from [dbo].[Classificacao]
where @@ROWCOUNT > 0 and [CodClassificacao] = scope_identity()',N'@0 varchar(255),@1 bit',@0='Mercado',@1=0
go
exec sp_executesql N'insert [dbo].[Classificacao]([Descricao], [Excluido])
values (@0, @1)
select [CodClassificacao]
from [dbo].[Classificacao]
where @@ROWCOUNT > 0 and [CodClassificacao] = scope_identity()',N'@0 varchar(255),@1 bit',@0='Concorrência',@1=0
go

我想知道如何一次插入EF将生成如下命令:

INSERT INTO Table (column)
VALUES ([array[0]]), ([array[1]]), ...

而不是一个插入foreach .. 有什么想法吗?

2 个答案:

答案 0 :(得分:1)

实体框架核心(3+)在此领域得到了显着改进。当有多个具有相同形状的插入时,对于Sql Server,它将生成MERGE条语句,而不是单独的INSERT条语句。

例如,添加10种新产品:

DECLARE @inserted0 TABLE ([Id] int, [_Position] [int]);
MERGE [Products] USING (
VALUES (@p0, @p1, @p2, @p3, @p4, 0),
(@p5, @p6, @p7, @p8, @p9, 1),
(@p10, @p11, @p12, @p13, @p14, 2),
(@p15, @p16, @p17, @p18, @p19, 3),
(@p20, @p21, @p22, @p23, @p24, 4),
(@p25, @p26, @p27, @p28, @p29, 5),
(@p30, @p31, @p32, @p33, @p34, 6),
(@p35, @p36, @p37, @p38, @p39, 7),
(@p40, @p41, @p42, @p43, @p44, 8),
(@p45, @p46, @p47, @p48, @p49, 9)) AS i ([Image], [ProductName], [QuantityPerUnit], [StartDate], [UnitPrice], _Position) ON 1=0
WHEN NOT MATCHED THEN
INSERT ([Image], [ProductName], [QuantityPerUnit], [StartDate], [UnitPrice])
VALUES (i.[Image], i.[ProductName], i.[QuantityPerUnit], i.[StartDate], i.[UnitPrice])
OUTPUT INSERTED.[Id], i._Position
INTO @inserted0;

SELECT [t].[Id], [t].[RowVersion] FROM [Products] t
INNER JOIN @inserted0 i ON ([t].[Id] = [i].[Id])
ORDER BY [i].[_Position];

结论SELECT用于将生成的IdRowVersion值反馈到C#对象中。

当有大量插入时,EF不会达到最大参数阈值,只会生成MERGE语句的多个块。

这与带有值构造函数的插入语句不同,但仍比无数个单独的插入要好得多。

答案 1 :(得分:0)

查看此帖子:Fastest Way of Inserting in Entity Framework

实体框架并不是真正意义上的开箱即用,但看起来人们已经创建了一些扩展:https://efbulkinsert.codeplex.com/