c# - dbContext An entity object cannot be referenced by multiple instances of IEntityChangeTracker -
so problem i'm having following. when going if statement, want delete entries cleardbinstallforgroupandheader() table installationbom. want add entries within newinstallationboms installationbom table , while doing calculating total cost, when want add line db.installationboms.add(newinstallationbom);, following error:
an entity object cannot referenced multiple instances of ientitychangetracker.
if (installationselected) { bool newentry = true; if (selectedquotedetails != null) { quotedetail thequotedetail = selectedquotedetails.firstordefault(x => x.groupnr == groupid && x.linetype == "i"); if (thequotedetail != null) { this.cleardbinstallforgroupandheader(); int position = selectedquotedetails.indexof(thequotedetail); newentry = false; thequotedetail.quantity = installqty; thequotedetail.unitcost = installcost; thequotedetail.unitprice = installprice; selectedquotedetails[position] = thequotedetail; db.quotedetails.attach(thequotedetail); db.entry(thequotedetail).state = entitystate.modified; db.savechanges(); decimal totalinstallationcost = 0; totalinstallationcost = addinstalltodbcalctotalcost(thequotedetail.line.value, groupid); newlines.unitcost = totalinstallationcost; newlines.unitprice = newlines.unitcost * (1 + (settings.marginpercentage / 100)); installcost = newlines.unitcost ?? 0; installprice = newlines.unitprice ?? 0; raisepropertychanged(() => selectedquotedetails); } } } public void cleardbinstallforgroupandheader() { try { using (quoteconfiguratorentities db = utilities.getcontext()) { list<installationbom> dblist = db.installationboms.where(x => x.quoteheaderid == this.selectedquoteheader.id && x.groupnr == this.selectedgroup.id) .tolist(); foreach (installationbom existinginstallationbom in dblist) { db.installationboms.remove(existinginstallationbom); } db.savechanges(); } } catch (exception ex) { this.message = ex.message + "\n\n" + ex.stacktrace; this.showerrormessage(); } } public decimal addinstalltodbcalctotalcost(decimal pline, long pgroupnr) { decimal totalinstallationcost = 0; try { using (quoteconfiguratorentities db = utilities.getcontext()) { foreach (installationbom newinstallationbom in this.newinstallationboms) { newinstallationbom.quoteheaderid = this.selectedquoteheader.id; newinstallationbom.groupnr = pgroupnr; newinstallationbom.linenumber = pline; totalinstallationcost += (newinstallationbom.quantity.value * newinstallationbom.cost.value); db.installationboms.add(newinstallationbom); db.savechanges(); } } } catch (exception ex) { this.message = ex.message + "\n\n" + ex.stacktrace; this.showerrormessage(); } return totalinstallationcost; } public void openinstallationoptionswindow(bool asthread = false) { try { if (asthread) { this.busy = true; this._thread = new thread(() => quoteconfiguratorviewmodel.openinstallationoptionswindow(this)); this._thread.isbackground = true; this._thread.start(); } else { using (quoteconfiguratorentities db = utilities.getcontext()) { observablecollection<installationbom> installbomlistgroup = new observablecollection<installationbom>(db.installationboms.where(x => x.quoteheaderid == this.selectedquoteheader.id && x.groupnr == this.selectedgroup.id).tolist()); if (installbomlistgroup != null) { if (!installbomlistgroup.any()) { clearinstallationbomentry(); newinstallationboms = new observablecollection<installationbom>(); } else if (installbomlistgroup.any()) { newinstallationboms = installbomlistgroup; } } messenger.default.send<openinstallationwindow>(new openinstallationwindow()); } } } catch (exception ex) { this.message = utilities.geterror(ex); } }
the problem newinstallationboms
attached in context. try add them in context in addinstalltodbcalctotalcost
.
solution 1: should use same context. detailed answer
solution 2: should first detach them in first context , attach them in second context. detailed answer.
solution 3 (credits grek40): if use asnotracking()
in first context. not tracked/cached. therefore can safely use in second context.
in stiuation it's better follow solution 1. if use dependency injection container, can make dbcontext per request. other this,you can manage lifetime of dbcontext on upper level or can make class disposable , manage db context in class.
Comments
Post a Comment