+无法跟踪实体类型的实例,因为另一个实例具有相同的键值

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

我有以下代码

            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;

ta.AccID 是 table ToxAccInfo 的主键。

问题是当我尝试在没有 ta.AccId = (long)Find(memid).Accid 的情况下保存更改时,它会创建另一行而不是更新原始行。但是,当我现在添加该行时,它失败并显示错误 The instance of entity type...cannot be tracked because another instance with the same key value.

过去 3 天我一直在寻找解决方法,但仍然无法正常工作。

谢谢。

我正在添加整个过程来创建要保存的内容 (ta) 和保存子程序

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;
        }

错误发生在 yield 调用 private ToxAccInfo UpdateMemAccount(ToxAccInfo UpAm) 之后,在 _db.ToxAccinfos.Update(UpAm);,我尝试使用 add 而不是 Update 仍然是同样的问题。

我使用以下代码从控制器调用 Updateboth,这两个方法在一个接口中。下面代码调用接口。

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;

这是我假设您的代码所做的:

FindAcc(memid) 将使用 DbContext select 基于 memid 的实体(这是您的唯一值),然后从中提取值。 之后,您创建另一个实例并为其分配相同的键以及您想要的修改值。

但不幸的是,AccId 是您的 PK,并且 ta.AccId = (long)Find(memid).Accid 使它成为另一个具有相同 ID 的新实例,该实例由 EF Core 本身跟踪,而它 select 由 FindAcc(memid).

您可能想做的事情: 如果您想更新该实体:

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

如果您想添加另一个实体:

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

可以找到更多信息here