Entity framework 5.0 handle optimistic concurrency exception?

后端 未结 2 1261
我在风中等你
我在风中等你 2020-12-13 02:52

When handling several potential exceptions during a context.SaveChanges() one of the exceptions is OptimisticConcurrency. Microsoft\'s documentatio

相关标签:
2条回答
  • 2020-12-13 03:11

    If your changes are only against the one entity (particular one row, not others tables etc), which is covered by the concurrency mechanism you are allowed to refresh context by disposing the old one and create new one. The thing is when the context is disposed every changed entities and not yet committed are detached from the context and the changes are lost. So be careful about the scope of your unit work!

        catch (DbUpdateConcurrencyException)
        {
            context.Dispose();
            context = new DBContext();
            Entity entity = context.Set<Entity>().Find(entityFromOldContext.Id);
    
            entity.Property1 = entityFromOldContext.Property1;
            entity.Property2 += 4;
    
            context.commit();
        }
    

    In the Entity I use extra property for controlling concurrency as follows:

    [Timestamp]
    public Byte[] RowVersion { get; set; }
    

    It is maybe not elegant way (and breaks UnitOfWork pattern), but it might be useful in some situations and finally an alternative to the above posts.

    0 讨论(0)
  • 2020-12-13 03:14

    The way how to solve concurrency exception in DbContext API reloads original entity:

    catch (DbUpdateConcurrencyException ex)
    {
        // Get failed entry
        var entry = ex.Entries.Single(...);
        // Overwrite original values with values from database but don't
        // touch current values where changes are held
        entry.OriginalValues.SetValues(entry.GetDatabaseValues());
    }
    

    You should also be able to use the mentioned code but you must get ObjectContext instance from your DbContext instance (it is just a wrapper around ObjectContext).

    catch (DbUpdateConcurrencyException ex)
    {
        var objContext = ((IObjectContextAdapter)context).ObjectContext;
        // Get failed entry
        var entry = ex.Entries.Single(...);
        // Now call refresh on ObjectContext
        objContext.Refresh(RefreshMode.ClientWins, entry.Entity);        
    }
    

    You may even try:

    objContext.Refresh(RefreshMode.ClientWins, ex.Entries.Select(e => e.Entity));
    
    0 讨论(0)
提交回复
热议问题