2012-11-30 30 views
0

我想处理一个批量插入过程中的情况,其中可能存在具有相同主键的实体,这当然会导致SaveChanges抛出异常。分离一个实体并在另一次尝试上保存上下文

这是我有:(计数随着时间的foreach循环迭代次数下降)

try 
{ 
    _context.SaveChanges(); 
    _context.Dispose(); 
    _context = null; 
    _context = SelectContext<T>(); 
    _commitCount = 0; 
} 
catch (System.Data.UpdateException updateEx) 
{ 
    //Remove from _context all the entries that errored in the SaveChange() process... 
    if (updateEx.StateEntries != null) 
    { 
     foreach (ObjectStateEntry stateEntry in updateEx.StateEntries) 
     { 

      if ((System.Data.EntityState)stateEntry.Entity.GetType().GetProperty("EntityState").GetValue(stateEntry.Entity, null) != System.Data.EntityState.Detached) 
      { 
       _context.Detach(stateEntry.Entity); 
      } 
     } 

} 

//Save context changes again this time without erroneous entries... 
try 
{ 
    _context.SaveChanges(); 
    _context.Dispose(); 
    _context = null; 
    _context = SelectContext<T>(); 
    _commitCount = 0; 
} 
catch (Exception ex) 
{     
    //Welp, at the point, I'm clueless... 
} 

如果我看在ObjectStateManager,实体确实去除

但它仍然在第二次尝试中抛出一个异常,喋喋不休地发出一声嘟PK。

我认为分离一个实体的原理是一样的,如果它从来没有在上下文中。我需要做其他事吗?

谢谢。

+0

任何你不想检查对象是否存在之前的原因? –

+0

究竟哪个对象? –

+1

你可以检查实体是否存在于分贝之前添加?我认为它比添加更好,并且在catch中分离 –

回答

0

这是我结束了我的情况做:

_context.ObjectStateManager.ChangeObjectState(stateEntry.Entity, System.Data.EntityState.Unchanged); 
_context.ApplyOriginalValues<T>(entityType, (T)stateEntry.Entity); 
_context.Detach(stateEntry.Entity); 

在那之后,我能够保存环境的变化。

1

Deatch不能完全撤消更改。根据msdn文档“只有实体被删除;如果有任何相关对象被同一个ObjectStateManager跟踪,那些将不会被自动分离。”

只有您传递给分离的实体被删除。其他更改将导致失败。会有争夺你的分贝?如果这个应用程序是对数据库进行更改的唯一方法,那么您可以使用context.Refresh(RefreshMode.StoreWins, object);取消更改,否则它会更复杂一些。

你必须这样做;

var entry = context.ObjectStateManager.GetObjectStateEntry(((IEntityWithKey)object).EntityKey); 

    for (int i = 0; i < entry.OriginalValues.FieldCount; i++) 

{ 

    entry.CurrentValues.SetValue(i, entry.OriginalValues[i]); 

} 

entry.AcceptChanges(); 

上面的代码使用ObjectSateManager所有修改的对象恢复到原来的状态,之后context.SaveChanges(); shoudl成功。

您可能也会觉得这有用http://dotnetadventurer.blogspot.com/2010/09/discarding-changes-to-objectcontext-in.html我还没有试过他的代码,我通常初始化我的上下文的方式不同,所以我不确定它是否可以与您的示例一起工作,但它非常简单,所以如果是这样,我会去。

+0

这就是我最终在我的案例中做的事情: –

相关问题