【问题标题】:DBUpdateException Entries only returning one item at a timeDBUpdateException 条目一次只返回一项
【发布时间】:2017-06-01 19:26:56
【问题描述】:

实体框架 6.0;视觉工作室 15; SQL 2016;

DbUpdateException.Entries 一次只生成一个条目。

我正在尝试将多个项目添加到数据库中。当我调用 .SaveChanges() 时,由于重复键,它会生成 DbUpdateException。我尝试使用以下代码消除具有重复键的条目:

    public void  SaveDB(CEntities db) 
    {        
        bool savecompleted = false;
                while (!savecompleted)
                {
                    savecompleted = true;
                    try
                    {
                        db.SaveChanges();
                    }
                    catch (DbUpdateException updateex)
                    {
                        foreach (DbEntityEntry item in updateex.Entries)
                            item.State = EntityState.Detached;
                        savecompleted = false;
                    }
               }
}

我的理解是 DbUpdateException.Entries 应该包含所有失败的实体。我一次只得到一个实体。如果我尝试添加 500 个实体并且它们都是重复的,它将尝试调用 .SaveChanges() 500 次。

我错过了什么

添加实体的代码是:

   public void CreateActivity()
          {
            CEntities db = new CEntities();

            commentfield = GetComment();

            var scans = from x in dt.AsEnumerable() where x.Field<string>("Printid") != "0000000" group x by x.Field<string>("Printid") into p select new { printid = p.Key, Qty = p.Count(), date = p.Max(x => x.Field<DateTime>(timefield)) };
            foreach (var scan in scans)
            {
                int jobno =
                    (from x in db.ManifestDatas where x.PrintId == scan.printid select x.JobNo).FirstOrDefault();
                JobActivity activity = new JobActivity();
                activity.Activity = activityfield;
                activity.Employee = int.Parse(scan.printid);
                activity.ActivityDate = scan.date;
                activity.Quantity = scan.Qty;
                activity.JobNo = jobno;
                activity.Comment = commentfield;
                db.JobActivities.Add(activity);
            }

            SaveDB(db);

        }  

【问题讨论】:

  • 向我们展示将条目添加到上下文的代码可能会更清楚。
  • 这里哪一列是主键列?
  • 主键是多列(Activity,Employee,ActivityDate,Jobno)。我明白为什么会出现异常,我想弄清楚为什么DbUpdateException.Entries 一次只返回一个项目。

标签: c# entity-framework exception-handling


【解决方案1】:

在实体框架的实际实现中出现这种情况的原因。 EF 中没有 BulkInsert 方法。因此,当 SaveChanges 执行时,对于每个添加的实体,它将像这样查询到数据库中:

exec sp_executesql N'INSERT [dbo].[JobActivity]([Activity], [Employee], [ActivityDate], [Quantity], [JobNo], [Comment])
VALUES (@0, @1, @2, @3, @4, @5) ...actual values for the first JobActivity
exec sp_executesql N'INSERT [dbo].[JobActivity]([Activity], [Employee], [ActivityDate], [Quantity], [JobNo], [Comment])
VALUES (@0, @1, @2, @3, @4, @5) ...actual values for the second JobActivity

等等。 因此,当第一个错误发生时,它会在一些异常中返回给调用者。如果您的违反主键错误是一种罕见的情况,您可以保留您的代码。但更好的选择是生成始终唯一的主键并防止在代码中插入重复项。

查看一些库以允许批量插入以提高 EntityFramework 中的性能(如果这很关键),例如 EntityFramework Extensions

【讨论】:

  • 谢谢,我只是想确保我没有做错任何事。在添加实体之前,我实际上继续执行了数据库查找。我遇到的主要问题是,有时会上传一个重复的数据文件,其中可能包含数以千计的交易,这些交易都是重复的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-18
  • 2022-01-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多