Entity Framework 6.0; Visual Studio 15; SQL 2016;
DbUpdateException.Entries一次只生成一个条目。
我试图将多个项目添加到数据库中。当我调用.SaveChanges()时,由于Duplicate Key,它会生成一个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);
}
答案 0 :(得分:0)
实际执行实体框架的原因。 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。