c# - DbContext.ChangeTracker.HasChanges is very slow -
my application uses entity framework 6.1.0 , dbcontext
api.
it's kind of cad system, , intended edit engineering documents. detect fact of changes in document, i'm using dbcontext.changetracker.haschanges
.
when document has large amount of data (approximately 20-25 thousands of entities), dbcontext.changetracker.haschanges
running very slow. since code used enable/disable "save" command, executes rather ui thread. this, in turn, hits application performance.
i've re-written fragment:
private lazy<dbcontext> context; public bool haschanges { { if (!context.isvaluecreated) { return false; } return context.value.changetracker.haschanges(); } }
to one:
public bool haschanges { { if (!context.isvaluecreated) { return false; } var objectstatemanager = ((iobjectcontextadapter)context.value).objectcontext.objectstatemanager; return objectstatemanager.getobjectstateentries(entitystate.added).any() || objectstatemanager.getobjectstateentries(entitystate.deleted).any() || objectstatemanager.getobjectstateentries(entitystate.modified).any(); } }
and (it's miracle!) works extremely fast.
looks dbchangetracker.haschanges
implementation isn't optimal. missing something?
in first code snippet call chain haschanges involves call detectchanges. when using snapshot change tracking detectchanges goes through tracked entities determine if have changed haschanges return correct result.
the second code snippet not call detectchanges instead asks state manager states knows about. if entity has been modified has not yet been detected, second code snippet may return wrong result.
there few ways of handling this, 1 of use change tracking proxies instead of snapshot change tracking. wrote blog series on detectchanges describes various options , tradeoffs in detail: http://blog.oneunicorn.com/2012/03/10/secrets-of-detectchanges-part-1-what-does-detectchanges-do/. recommend reading through can make choice kind of change tracking best application.
Comments
Post a Comment