我正在寻找插入实体框架的最快方法。
我之所以问这个问题,是因为您有一个活动的TransactionScope,并且插入量很大(4000+)。它可能会持续超过10分钟(事务的默认超时),这将导致事务不完整。
我正在寻找插入实体框架的最快方法。
我之所以问这个问题,是因为您有一个活动的TransactionScope,并且插入量很大(4000+)。它可能会持续超过10分钟(事务的默认超时),这将导致事务不完整。
当前回答
保存列表的最快方法之一必须应用以下代码
context.Configuration.AutoDetectChangesEnabled = false;
context.Configuration.ValidateOnSaveEnabled = false;
AutoDetectChangesEnabled=false
添加、添加范围和保存更改:无法检测更改。
ValidateOnSaveEnabled=false;
未检测到更改跟踪器
您必须添加nuget
Install-Package Z.EntityFramework.Extensions
现在您可以使用以下代码
var context = new MyContext();
context.Configuration.AutoDetectChangesEnabled = false;
context.Configuration.ValidateOnSaveEnabled = false;
context.BulkInsert(list);
context.BulkSaveChanges();
其他回答
尝试使用存储过程来获取要插入的数据的XML。
秘密是插入到相同的空白暂存表中。插件快速发光。然后在主大表中运行一个单独的插入。然后截断临时表,为下一批做好准备。
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
这种组合可以很好地提高速度。
context.Configuration.AutoDetectChangesEnabled = false;
context.Configuration.ValidateOnSaveEnabled = false;
我对上面的@Slauma示例进行了一个通用扩展;
public static class DataExtensions
{
public static DbContext AddToContext<T>(this DbContext context, object entity, int count, int commitCount, bool recreateContext, Func<DbContext> contextCreator)
{
context.Set(typeof(T)).Add((T)entity);
if (count % commitCount == 0)
{
context.SaveChanges();
if (recreateContext)
{
context.Dispose();
context = contextCreator.Invoke();
context.Configuration.AutoDetectChangesEnabled = false;
}
}
return context;
}
}
用法:
public void AddEntities(List<YourEntity> entities)
{
using (var transactionScope = new TransactionScope())
{
DbContext context = new YourContext();
int count = 0;
foreach (var entity in entities)
{
++count;
context = context.AddToContext<TenancyNote>(entity, count, 100, true,
() => new YourContext());
}
context.SaveChanges();
transactionScope.Complete();
}
}
使用此技术可以提高实体框架中插入记录的速度。这里我使用一个简单的存储过程来插入记录。为了执行这个存储过程,我使用实体框架的.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 = "";
}
}