0

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;
2
  • Can you share your code of updating ta? Commented Aug 12, 2021 at 1:54
  • Can you please go through, I have added more code. Commented Aug 13, 2021 at 6:41

1 Answer 1

1

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

Sign up to request clarification or add additional context in comments.

3 Comments

Thank you for your contribution, but it still will not work, still giving the same error. If I add a break point at the SaveChange line and view the content of ta, the AccId is 0 when I do not force ta.AccId = (long)Find(memid).Accid. It also creates a new entry for the transaction instead of updated the existing entry.
In case if i missout something... ToxAccInfo ta = new ToxAccInfo(); will always make ta a new instance to be added to your database. And the AccId should be 0 (if you use integer as PK). Then after SaveChange() execution, the AccId should be update by the new Id that got generated by Db. P/s: Don't forget to config Db auto generate for the key
It should look like [Key] [DatabaseGenerated(DatabaseGeneratedOption.Identity)] // Optional public int Id { get; set; } or if using in fluent API: builder.HasKey(x => x.Id); builder.Property(x => x.Id).ValueGeneratedOnAdd(); // Optional

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.