c# - Setting values and handling concurrency in EF 6 -
i using ef 6.1 , service update method looks so
public async override task<int> updateasync(module updated) { var entity = await _context.modules .where(e => e.id == updated.id) .firstordefaultasync(); // update existing values _context.entry(entity).currentvalues.setvalues(updated); // not update _context.setmodified(entity, "addonlyproperty", false); return await base.updateasync(entity); }
my base updateasync looks so
public async virtual task<int> updateasync(t updated) { var results = await validateasync(updated); if (!results.isvalid) { throw new validationexception(results.errors); } if (_context.getstate(updated) == entitystate.detached) { _context.set<t>().attach(updated); _context.setstate(updated, entitystate.modified); } // not want createddate change when update being done _context.setmodified(updated, "createddate", false); _context.setmodified(updated, "createdbyuserid", false); return await _context.savechangesasync(); }
this method simple, copies changes updated entity, way ef apply changes needed when creates sql.
my problem concurrency doesnt seem working, expect dbconcurrencyexception thrown?
here basic module object
public class module : entitybase, ientityversion, ientitydelete { public long id { get; set; } public string name { get; set; } public byte[] rowversion { get; set; } }
i have configured rowversion rowversion field in module.config file, so
this.property(e => e.rowversion) .isrowversion();
now when perform update old rowversion value, update seems still take place? have missed configuration setting or doing wrong?
should exception thrown, or should checking if rowversion values match myself?
you retrieve record.
you modify record.
someone else modifies record too, , saves change.
you retrieve record again, , update values match desired values.
you save changes.
the problem here "you retrieve record again" step. because after other person saved changes, new row version value already. step need skip.
one way of handling using 1 context
throughout process, , leaving entity-to-be-modified attached context. entity framework able keep track of original values.
another way of handling keeping track of original values yourself. when want save changes, create detached entity, set properties original values, attach context, , set properties modified values.
actually, thinking more, instead of using on ef's concurrency handling, should able trivially code own here:
var entity = await _context.modules .where(e => e.id == updated.id) .firstordefaultasync(); if (entity == null) { ... // throw exception record not existing in database } if (bitconverter.toint64(entity.rowversion, 0) != bitconverter.toint64(updated.rowversion, 0)) { ... // throw exception record having been updated in database } ... // existing code update entity can go here
Comments
Post a Comment