【问题标题】:How to make bypass insert failed objects in Entity Framework?如何在实体框架中绕过插入失败的对象?
【发布时间】:2017-10-25 04:27:01
【问题描述】:

在我的一个项目中,使用了实体框架。

我遇到了一个性能很糟糕的情况。当有多条记录需要一条一条插入到一个表中时,大概50~500不是很确定,但是非常庞大。

一开始我用的是:

dbcontext.Adds.Add(alist);

进行插入。但很快我发现,一旦存在 1 个包含无效数据且无法正确插入数据库的对象,则无法插入任何数据!所有数据相互关联,不能绕过任何不正确的数据。

这是我的解决方案:

foreach(var a in alist)
{
    //...
    try
    {
        dbcontext.Adds.Add(a);
        dbcontext.SaveChanges();
    }
    catch (Exception ex)
    {
        // just log and bypass one by one
        log4net.LogManager.GetLogger("NOTSAVE").Info(a.ToString());
    }
}

现在,它可以正常工作了。

但是有个大问题就是性能很差!客户端可能会为每个操作等待几秒钟。而且自定义反馈也更糟糕。

有没有人知道任何其他提高性能的解决方案?最好在 500ms ~ 1 秒内完成。但是现在,一旦记录 > 100,它每次可能花费超过 1 秒。结果,每个客户都通过 UI 操作时出现明显且频繁的停顿。

【问题讨论】:

  • 你可以使用AddRange然后anylize异常,排除特定的无效项目,然后再试一次。

标签: entity-framework batch-insert


【解决方案1】:

您可以做的第一件事也是重要的事情是关闭AutoDetectChangesEnabled,它会对性能产生巨大影响。

dbcontext.Configuration.AutoDetectChangesEnabled = false;
foreach(var a in alist)
{
    //...
    try
    {
        dbcontext.Adds.Add(a);
        dbcontext.SaveChanges();
    }
    catch (Exception ex)
    {
        // just log and bypass one by one
        log4net.LogManager.GetLogger("NOTSAVE").Info(a.ToString());
    }
}
dbcontext.Configuration.AutoDetectChangesEnabled = true;

阅读这篇文章了解更多信息:EntityFramework Performance and AutoDetectChanges

您可以使用第三方库:

您可以使用System.Data.SqlClient.SqlBulkCopy inADO.NET,速度非常快。

【讨论】:

  • 非常感谢,添加后 dbcontext.Configuration.AutoDetectChangesEnabled = false;我测试的时间成本不到之前情况的一半。
猜你喜欢
  • 2014-05-04
  • 1970-01-01
  • 1970-01-01
  • 2018-04-24
  • 1970-01-01
  • 1970-01-01
  • 2015-01-06
  • 2011-08-24
  • 1970-01-01
相关资源
最近更新 更多