主键值错误

时间:2018-02-14 21:43:13

标签: c# entity-framework

  

附加' app.Models.LookupMatchStatus'类型的实体失败,因为同一类型的另一个实体已具有相同的主键值。使用'附加'方法或将实体的状态设置为“未更改”#39;或者'修改'如果图中的任何实体具有冲突的键值。这可能是因为某些实体是新的并且尚未收到数据库生成的键值。在这种情况下,请使用'添加'方法或“添加”#39;实体状态跟踪图形,然后将非新实体的状态设置为“未更改”。或者'修改'作为适当的   我查看了一些有关此问题的帖子,但不知道接受的答案是否适用于我的问题。

我们的用户在使用我们构建的应用程序时会出现间歇性错误。 由于我无法重新创建问题,任何人都可以告诉我,如果更换以下内容可以解决问题:

var vMatchStatus = context.LookupMatchStatus.Single(x => x.Code == "UMTC");

var vMatchStatus = context.LookupMatchStatus.**AsNoTracking()**
                                .Single(x => x.Code == "UMTC");
public ActionResult UpdateUnmatchedRecord(long? SelectedId)
{
    if (Session["user"] != null)
    {
        if (SelectedId == null)
        {
            if (TempData["Data"] != null)
            {
                long globalID = GetSequence();
                using (HCPInsightsEntities context = new HCPInsightsEntities())
                {
                    ListMatchDetails unResolvedRecord = (ListMatchDetails)TempData["Data"];
                    if (!TempData.Keys.Contains("ListMatchId"))
                    {
                        TempData.Add("ListMatchId", unResolvedRecord.ListMatchId);
                    }
                    var vMatchStatus = context.LookupMatchStatus.AsNoTracking().Single(x => x.Code == "UMTC");
                    //Original Below
                    //var vMatchStatus = context.LookupMatchStatus.Single(x => x.Code == "UMTC");
                    unResolvedRecord.LkupMatchStatusId = vMatchStatus.LkupMatchStatusId;
                    unResolvedRecord.RowSelected = null;
                    unResolvedRecord.GlobalId = globalID;

                    if (TryValidateModel(unResolvedRecord))
                    {
                        context.ListMatchDetails.Attach(unResolvedRecord);
                        var entry = context.Entry(unResolvedRecord);
                        entry.Property(x => x.LkupMatchStatusId).IsModified = true;
                        entry.Property(x => x.RowSelected).IsModified = true;
                        entry.Property(x => x.GlobalId).IsModified = true;
                        context.SaveChanges();
                        UpdateListMatchJob(unResolvedRecord.ListMatchId, false);
                        Session["reconcile"] = null;
                    }
                }
            }
        }
        return RedirectToAction("Reconcile");
    }
    else
    {
        return RedirectToAction("SignIn", "Login");
    }
}

1 个答案:

答案 0 :(得分:0)

  

任何人都可以告诉我,如果更换以下内容可以解决问题:

也许

让我们首先开始为什么存在问题。第一个ORM,默认情况下,缓存是通过内部缓存中的数据库检索数据而创建的模型,包含在DbContext内。这样做是为了尝试减少对数据库的调用次数,并允许在不影响数据库的情况下对上下文进行本地更改,以便它可以优化nd在SaveChanges()上正确排序sql事件。

在您的示例代码中,它通过以下方式检索LookupMatchStatus

var vMatchStatus = context.LookupMatchStatus.Single(x => x.Code == "UMTC");

这会将项目放在本地缓存中。然后代码尝试通过以下方式在缓存中放置具有相同类型的相同密钥的另一个项目:

context.ListMatchDetails.Attach(unResolvedRecord);

这只是一个假设,因为你没有给出任何堆栈跟踪,也没有引发异常的特定行,因此很难确定错误是如何发生的,为什么以及如何解决它。

因此,只需使用AsNoTracking()解决问题......好吧也许。该方法旨在防止模型插入缓存。我不知道该特定行是否是问题或其他原因。