Entity Framework: Can't save data because of tracking

asp.net-core-2.0 c# entity-framework entity-framework-core

Question

I have got a complex class. Feedback and Steps. I am using SQL database and .Net Core 2. I can save main properties but can't save the sub class FeedbackSteps properties

public class FeedbackModel
{
    [Key]
    public int FeedBackID { get; set; }
    public DateTime FBDate { get; set; }
    public bool? VideoStatus { get; set; }
    public string VideoDetail { get; set; }
    public string PITFeedBack { get; set; }
    public int ActivityID { get; set; }
    public virtual ActivityModel Activity { get; set; }
    public int ClientID { get; set; }
    public virtual ClientModel Client { get; set; }
    public int? SupportPlanID { get; set; }
    public virtual SupportPlanModel SupportPlan { get; set; }
    public int EmployeeID { get; set; }
    public virtual Employee Employee { get; set; }
    public bool FeedbackStatus { get; set; } = true;

    virtual public List<FeedbackStepModel> FeedbackSteps { get; set; }
}

and

public class FeedbackStepModel
{
    [Key]
    public int FeedbackStepID { get; set; }
    public int FeedbackID { get; set; } = 0;
    public int SupportPlanID { get; set; }    
    public int StepNumber { get; set; }
    public string StepDetail { get; set; }
    public string AchivmentStatus { get; set; }
    public string AchivmentComment { get; set; }

}

This is the post method. View returns Edited or Updated feedback and i just want to update the database with new data

    [HttpPost]
    public IActionResult Edit(FeedbackModel feedback)
    {
        if (ModelState.IsValid)
        {
            feedbackRepository.Save(feedback);
            TempData["message"] = $"Feedback has been saved";
            return RedirectToAction("Index");
        }
    }

after EDIT, I would like to save it...

    public void Save(FeedbackModel feedback)
    {
        if (feedback.FeedBackID == 0)
        {
            context.FeedbackModels.Add(feedback);
        }
        else
        {
            FeedbackModel dbEntry = context.FeedbackModels.Include(s => s.FeedbackSteps).FirstOrDefault(a => a.FeedBackID == feedback.FeedBackID);

            if (dbEntry != null)
            {
                dbEntry.FeedBackID = feedback.FeedBackID;
                dbEntry.FBDate = feedback.FBDate;
                dbEntry.VideoStatus = feedback.VideoStatus;
                dbEntry.VideoDetail = feedback.VideoDetail;
                dbEntry.SupportPlanID = feedback.SupportPlanID;
                dbEntry.ActivityID = feedback.ActivityID;
                dbEntry.PITFeedBack = feedback.PITFeedBack;
                dbEntry.ClientID = feedback.ClientID;
                dbEntry.EmployeeID = feedback.EmployeeID;                   
                dbEntry.FeedbackStatus = feedback.FeedbackStatus;
                dbEntry.FeedbackSteps = feedback.FeedbackSteps;
            }
        }
        context.SaveChanges();
    }

But it gives me this error all the time

Message=The instance of entity type 'FeedbackStepModel' cannot be tracked because another instance with the key value '{FeedbackStepID: 1}' is already being tracked. 
When attaching existing entities, ensure that only one entity instance with a given key value is attached.
1
1
2/10/2019 6:17:23 PM

Accepted Answer

Your FeedbackModel update operation with children (FeedbackSteps) should be as follows:

FeedbackModel dbEntry = context.FeedbackModels.Include(s => s.FeedbackSteps).FirstOrDefault(a => a.FeedBackID == feedback.FeedBackID);

if (dbEntry != null)
{
      dbEntry.FeedBackID = feedback.FeedBackID;
      dbEntry.FBDate = feedback.FBDate;
      dbEntry.VideoStatus = feedback.VideoStatus;
      dbEntry.VideoDetail = feedback.VideoDetail;
      dbEntry.SupportPlanID = feedback.SupportPlanID;
      dbEntry.ActivityID = feedback.ActivityID;
      dbEntry.PITFeedBack = feedback.PITFeedBack;
      dbEntry.ClientID = feedback.ClientID;
      dbEntry.EmployeeID = feedback.EmployeeID;                   
      dbEntry.FeedbackStatus = feedback.FeedbackStatus;

      dbEntry.FeedbackSteps.Clear(); // First you have to clear the existing feedBackSteps

      foreach(FeedbackStep feedBackStep in feedback.FeedbackSteps)
      {
         dbEntry.FeedbackSteps.Add(feedBackStep); // You have to add new and updated feedBackStep here.
      }
}

If dbEntry.FeedbackSteps.Clear(); does not work (may be in EF Core 2.0 or lower Clear() does not work) then replace dbEntry.FeedbackSteps.Clear(); with the following code:

foreach(FeedbackStep feedbackStepToBeRemoved in dbEntry.FeedbackSteps)
{
   context.Remove(feedbackStepToBeRemoved);
}
1
2/10/2019 5:48:28 PM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow