我正在寻找插入实体框架的最快方法。
我之所以问这个问题,是因为您有一个活动的TransactionScope,并且插入量很大(4000+)。它可能会持续超过10分钟(事务的默认超时),这将导致事务不完整。
我正在寻找插入实体框架的最快方法。
我之所以问这个问题,是因为您有一个活动的TransactionScope,并且插入量很大(4000+)。它可能会持续超过10分钟(事务的默认超时),这将导致事务不完整。
当前回答
秘密是插入到相同的空白暂存表中。插件快速发光。然后在主大表中运行一个单独的插入。然后截断临时表,为下一批做好准备。
ie.
insert into some_staging_table using Entity Framework.
-- Single insert into main table (this could be a tiny stored proc call)
insert into some_main_already_large_table (columns...)
select (columns...) from some_staging_table
truncate table some_staging_table
其他回答
记下几点,这是我的实施,我的改进以及其他回答和评论。
改进:
从我的实体获取SQL连接字符串仅在某些部分使用SQLBulk,其余部分仅使用实体框架使用与SQL数据库相同的日期表列名,无需映射每个列使用与SQL Datatable相同的Datatable名称public void InsertBulkDatatable(DataTable数据表){EntityConnectionStringBuilder entityBuilder=新的EntityConnectionStringBuilder(ConfigurationManager.ConnectionStrings[“MyDbContextConnectionName”].ConnectionString);string cs=entityBuilder.ProviderConnectionString;使用(varconnection=newSqlConnection(cs)){SqlTransaction事务=null;connection.Open();尝试{transaction=connection.BegginTransaction();使用(var sqlBulkCopy=新的sqlBulkCopy(连接,SqlBulkCopyOptions.TableLock,事务)){sqlBulkCopy.DestinationTableName=dataTable.TableName//使用SQL数据表在c中命名数据表#//映射列foreach(dataTable.Columns中的DataColumn列){sqlBulkCopy.ColumnMappings.Add(column.ColumnName,column.ColumnName);}sqlBulkCopy.WriteToServer(数据表);}transaction.Commit();}catch(异常){transaction.Rollback();}}}
使用此技术可以提高实体框架中插入记录的速度。这里我使用一个简单的存储过程来插入记录。为了执行这个存储过程,我使用实体框架的.FromSql()方法来执行Raw SQL。
存储过程代码:
CREATE PROCEDURE TestProc
@FirstParam VARCHAR(50),
@SecondParam VARCHAR(50)
AS
Insert into SomeTable(Name, Address) values(@FirstParam, @SecondParam)
GO
接下来,循环遍历所有4000条记录,并添加执行存储的
该过程每100次循环一次。
为此,我创建了一个字符串查询来执行这个过程,并继续将每一组记录附加到它。
然后检查循环是否以100的倍数运行,在这种情况下,使用.FromSql()执行它。
所以对于4000条记录,我只需要执行以下步骤4000/100=40次。
检查以下代码:
string execQuery = "";
var context = new MyContext();
for (int i = 0; i < 4000; i++)
{
execQuery += "EXEC TestProc @FirstParam = 'First'" + i + "'', @SecondParam = 'Second'" + i + "''";
if (i % 100 == 0)
{
context.Student.FromSql(execQuery);
execQuery = "";
}
}
秘密是插入到相同的空白暂存表中。插件快速发光。然后在主大表中运行一个单独的插入。然后截断临时表,为下一批做好准备。
ie.
insert into some_staging_table using Entity Framework.
-- Single insert into main table (this could be a tiny stored proc call)
insert into some_main_already_large_table (columns...)
select (columns...) from some_staging_table
truncate table some_staging_table
据我所知,EntityFramework中没有BulkInsert来提高大型插件的性能。
在这种情况下,您可以使用ADO.net中的SqlBulkCopy来解决问题
最快的方法是使用批量插入扩展,这是我开发的
注:这是一种商业产品,不是免费的
它使用SqlBulkCopy和自定义数据读取器来获得最大性能。因此,它比使用常规插入或AddRange快20倍以上
用法非常简单
context.BulkInsert(hugeAmountOfEntities);