InvalidOperationException:无法跟踪实体类型“ Vessels”>的实例,因为另一个实例

时间:2020-09-01 16:54:21

标签: c# asp.net-core

我的编辑页面上出现了最奇怪的错误。

InvalidOperationException:实体类型“容器”的实例 无法跟踪,因为另一个实例具有相同的键值 {'Id'}已被跟踪。附加现有实体时, 确保只有一个具有给定键值的实体实例是 附上。考虑使用 'DbContextOptionsBuilder.EnableSensitiveDataLogging'以查看 冲突的键值。

我用于保存功能的代码如下,我需要使用AsNoTracking吗?我想将方法​​中的json旧值和新值保存到审计跟踪记录中,但是我猜它在抱怨原因是我正在访问_context.Vessel在“容器编辑”方法中?

我正在使用asp.net core 3.1和ef Core 3.1.7

// POST: Vessels/Edit/5
// To protect from overposting attacks, enable the specific properties you want to bind to, for 
// more details, see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(int id, [Bind("Id,Name,Displacement_Summer,Draught,Fuel_Consumption,Speed_MAX,Speed_Serivce,Liquid_Oil,CountryOfOrigon,CompanyId,Role,CallSign,MMSI,GrossTonnage,DateOwnedFrom,DateOwnedTo,IMONumber,Flag,Name,Company,Country,CallSign,MMSI,FishingNumber,IMONumber,LOALength,YearBuilt,VesselType,Active,isDeleted,isActive,CreatedDate,CreatedBy,MISObjectId,RelationShipId,DateBuilt,DateOSS,OfficalNumber")] Vessels vessels) {
    if (id != vessels.Id) {
        return NotFound();
    }

    Int32.TryParse(TempData.Peek("CaseId").ToString(), out Int32 resultCaseId);
    var oldValues = _context.Vessels
        .FirstOrDefault(w => w.Id == id  && w.isActive == true && w.isDeleted == false);
    string oldValuesjson = JsonConvert.SerializeObject(oldValues, Formatting.Indented);


    if (ModelState.IsValid) {

        var realtionShipId = Int32.TryParse(HttpContext.Session.GetString("relationShipId"), out int resultRelationshipId);

        var todayDate = DateTime.Now;
        try {

            vessels.isActive = true;
            vessels.isDeleted = false;
            vessels.Flag = vessels.Flag.ToLower();
            // we only want to change this information if the date is differnt no need if its the same person.
            if (vessels.LastModfiedDate != todayDate) {
                vessels.LastModfiedDate = DateTime.Now;
                vessels.LastModfiedBy = HttpContext.Session.GetString("Intitals");

            }
            if (HttpContext.Session.GetString("Intitals") != vessels.LastModfiedBy)
                vessels.LastModfiedBy = HttpContext.Session.GetString("Intitals");
            vessels.isActive = true;
            vessels.isDeleted = false;
            vessels.MISObjectId = resultCaseId;
            _context.Update(vessels);
            await _context.SaveChangesAsync();


            string newValuesjson = JsonConvert.SerializeObject(vessels, Formatting.Indented);




            var tennantId = await GetCurrentTennantId();
            var caseOfficer = _context.Users.Where(w => w.Id == tennantId.ToString()).FirstOrDefault();


            MISAuditTrail _auditrail = new MISAuditTrail();
            _auditrail.MISObjectId = resultCaseId;
            _auditrail.TennantId = tennantId;
            _auditrail.Action = "Vessel Updated ";
            _auditrail.Update= vessels.Name;
            _auditrail.CreatedBy = caseOfficer.FirstName;
            _auditrail.CreatedDate = DateTime.Now;
            _auditrail.isActive = true;
            _auditrail.isDeleted = false;
            _auditrail.OldFieldValues = oldValuesjson;
            _auditrail.NewFieldValues = newValuesjson;
            

            _context.Add(_auditrail);
            await _context.SaveChangesAsync();

            _toast.AddSuccessToastMessage($"You successfully Updated a Vessel  {vessels.Id.ToString("d8")} for ENF {resultCaseId.ToString("d8")}");

        } catch (Exception ex) {
            if (!VesselsExists(vessels.Id)) {
                return NotFound();
            } else {
                throw;
            }
        }
        SetupViewBags();
        return RedirectToAction("Edit", "MisObjects", new { Id = resultCaseId });


    }
    SetupViewBags();
    return View(vessels);
}

此调用的AsNoTracking()足够了。

var oldValues = _context.Vessels.AsNoTracking()
            .FirstOrDefault(w => w.Id == id  && w.isActive == true && w.isDeleted == false);

InvalidOperationException:由于另一个实例,无法跟踪实体类型'Vessels'>的实例

1 个答案:

答案 0 :(得分:0)

此调用的AsNoTracking()足够了。

我认为这已经足够,请看看this

要在ef core中更新数据,您还可以使用以下编码来避免错误:

           var oldValues = _context.Vessels.FirstOrDefault(w => w.Id == id  && 
                           w.isActive == true && w.isDeleted == false);
            oldValues.isActive = true;
            oldValues.isDeleted = false;
            oldValues.Flag = vessels.Flag.ToLower();
            // we only want to change this information if the date is differnt no need if its the same person.
            if (vessels.LastModfiedDate != todayDate)
            {
                oldValues.LastModfiedDate = DateTime.Now;
                oldValues.LastModfiedBy = HttpContext.Session.GetString("Intitals");

            }
            if (HttpContext.Session.GetString("Intitals") != vessels.LastModfiedBy)
                oldValues.LastModfiedBy = HttpContext.Session.GetString("Intitals");
            oldValues.isActive = true;
            oldValues.isDeleted = false;
            oldValues.MISObjectId = resultCaseId;
            _context.Update(oldValues);
           await _context.SaveChangesAsync();