Search code examples
c#asp.netasp.net-coreasp.net-mvc-5

The instance of entity type +cannot be tracked because another instance with the same key value


I have the following code

            double csave = (double)FindAcc(memid).MovAmt;
            double psave = (double)FindAcc(memid).VolSafe;
            double psaveamt = (double)FindAcc(memid).PriSave;
            Single compAmt = 0;
            ToxAccInfo ta =  new ToxAccInfo();
            ta.MemId = (int?)memid;
            ta.AccId = (long)FindAcc(memid).AccId;

The ta.AccID is the primary key for the table ToxAccInfo.

Issue is when I attempt to save changes without the ta.AccId = (long)Find(memid).Accid, it creates another line instead of updating the original. But, when I now add the line, it fails with the error The instance of entity type...cannot be tracked because another instance with the same key value.

I have spent the past 3 days trying to find a work around but still can't get it to work.

Thank you.

I am adding the whole procedure to create what is to be saved (ta) and the saving subroutine

public IEnumerable<ToxAccInfo> UpdateBoth(DateTime stdate, DateTime spdate, long memid, bool chkcomp, bool chkvol)
        {
            double csave = (double)FindAcc(memid).MovAmt;
            double psave = (double)FindAcc(memid).VolSafe;
            double psaveamt = (double)FindAcc(memid).PriSave;
            Single compAmt = 0;
            var ta =  new ToxAccInfo();
            ta.MemId = (int?)memid;
            //ta.AccId = (long)FindAcc(memid).AccId;
            for (DateTime curdate = stdate; curdate <= spdate; curdate = curdate.AddMonths(1))
            {
                if (GoAhead(memid, curdate))
                {

                    
                    ta.MovAmt = csave;
                    ta.VolSafe = psave;
                    if (chkvol == true)
                    {
                        ta.VolSafe = psave + psaveamt;
                        //ta.VolSafe += psaveamt;
                    }
                    if (curdate.Month > 1 && curdate.Year >= 2011)
                    {
                        compAmt = 1000;
                    }
                    else
                    {
                        compAmt = 200;
                    }
                    if (chkcomp == true)
                    {
                        ta.MovAmt = csave + compAmt;   //do the check for year it changed to 1000
                        
                    }
                    ta.Done = curdate;                                                                                                                                                                                                                                                                                                                                                                                                                                     
                    ta.Udate = curdate;
                    ta.Amt = compAmt + psaveamt;

                    //check for interest for month 12 and year greater than 2007.
                    if (curdate.Month == 12 && curdate.Year >= 2017)
                    {
                                                ta.VolSafe = doInterest((decimal)ta.VolSafe);
                        ta.MovAmt = doInterest((decimal)ta.MovAmt);
                        
                        psave = (double)ta.VolSafe;
                        csave = (double)ta.MovAmt;
                        goto jumper;
                    }
                    //psave += psaveamt;
                    //csave += compAmt;
                    psave = (double)ta.VolSafe;
                    csave = (double)ta.MovAmt;
                   

                jumper:;
           
                }
            }
            yield return UpdateMemAccount(ta);
         
        }


 private ToxAccInfo UpdateMemAccount(ToxAccInfo UpAm)
        {
            
            _db.ToxAccInfos.Update(UpAm);
            _db.SaveChanges();
            return null;
        }

The error occurs after the yield calls private ToxAccInfo UpdateMemAccount(ToxAccInfo UpAm), at _db.ToxAccinfos.Update(UpAm);, I have tried using add instead of Update still the same issue.

I call Updateboth from the controller with the following code, the two methods are in an interface. The code below calls the interface.

case "Commit Update":
                            ViewData["taa"] = _ar.UpdateBoth(stdate, eddate, (int)_ar.FindAcc(long.Parse(HttpContext.Session.GetString("memberid"))).MemId, chkcomp, chkvol).ToList();
                            ViewBag.isSet = false;
                            break;

Solution

  • Here is what i assuming your code doing:

    FindAcc(memid) will use the DbContext to select the entity base on the memid (this is your unique value), then extract the value out of it. After that, you create another instance and assign the same key to that along with the modified values you want.

    But unfortunately, the AccId is your PK, and ta.AccId = (long)Find(memid).Accid make it another new instance with the same Id that got tracked by the EF Core itself while it select the entity back by the FindAcc(memid).

    What you might want to do: If you want to update that entity:

    var entityFromDb = FindAcc(memid);
    entityFromDb.volSafe = SomeNewValueHere;
    YourDbContext.SaveChange();
    

    If you want to add another entity:

    var entityFromDb = FindAcc(memid);
    var ta =  new ToxAccInfo();
    ta.volSafe = SomeNewValueHere;
    YourDbContext.YourToxAccInfoSet.Add(ta);
    YourDbContext.SaveChange();
    

    Furthur information can be found here