entity framework 6 - Improve long running EF query with AsNoTracking -
i'm using entity framework v6.1.3 , 1 query tacking > 10s run application. takes < 1s when adding asnotracking() call:
public ilist<job> getbyerpheaderids(string[] headerids) { return base.query() .include(j => j.preferredbranch) .include(j => j.jobtype) .include(j => j.technicians) .include(j => j.gmcjobstates) .where(j => headerids.contains(j.erpserviceorderid)) .asnotracking() .tolist(); }
the getbyerpheaderids() method gets array 400 elements. problem need save database after modify items retrieved query. down context use following code manage entities state:
public virtual void save(tentity entity) { if (_context.entry(entity).state == entitystate.detached) { if (entity.isnew) { _dbset.add(entity); } else { var cachedentity = _dbset.local.firstordefault(x => x.equals(entity)); if (cachedentity != null) _context.entry(cachedentity).state = entitystate.detached; _context.entry(entity).state = entitystate.modified; } } else { _context.entry(entity).state = entitystate.modified; } if (!_context.isunitofworkactive) { _context.savechanges(); } }
when "modified" state entity dbupdateexception or duplicated entries
ex.innerexception.innerexception {"violation of primary key constraint 'pk_dbo.technicianjob'. cannot insert duplicate key in object 'dbo.technicianjob'. duplicate key value (1039, 239).\r\nthe statement has been terminated."} system.exception {system.data.sqlclient.sqlexception}
update1 : in example i'm trying save "job" entity database. entity contains references other tables, in case, reference table "technicianjob". looks when detached entity retrieved database, not retrieved table dependencies properly. think why i'm getting exception, because trying save entity in database.
update2 : how looks repository after reading article:
public virtual void save(tentity entity) { if (_context.entry(entity).state == entitystate.detached) { if (entity.isnew) { _dbset.add(entity); } else { var cachedentity = _dbset.local.firstordefault(x => x.equals(entity)); if (cachedentity != null) { var cachedentry = _context.entry(cachedentity); cachedentry.currentvalues.setvalues(entity); } else { var entry = _context.entry(entity); entry.state = entitystate.modified; } } } else { _context.entry(entity).state = entitystate.modified; } if (!_context.isunitofworkactive) { _context.savechanges(); } }
your generic save method, depends on changetracking. or @ least entities in correct state.
i suggest attach job entities before modifing them , calling save()
context.jobs.attach(job);
Comments
Post a Comment