2

I am trying to update the record of an item as follows

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(int id, [Bind("Id,Label,Description,LessonId,Position,FileName,Format,Status")] Content content)
{
      if (id != content.Id)
      {
         return NotFound();
      }

      var existingContent = await _context.Contents.FindAsync(id).ConfigureAwait(false);

      if (existingContent == null)
      {
         return NotFound();
      }

      string fileToDelete = null;

      if (ModelState.IsValid)
      {
          try
          {

            if (Request.Form.Files["FileName"] != null)
            {
               IFormFile uploadedFile = Request.Form.Files["FileName"];
               var lesson_mimetype = uploadedFile.ContentType;

               string[] extensions = new string[] { ".jpeg", ".jpg", ".gif", ".png", ".mp4", ".mp3", ".pdf" };

               ResponseMsg fileTypeValidationMsg = FileUploadHelper.ValidateFileExtension(uploadedFile, extensions);

               if (!fileTypeValidationMsg.ResponseStatus)
               {
                   ModelState.AddModelError("FileName", fileTypeValidationMsg.ResponseDescription);
               }

               ResponseMsg filesizeValidationMsg = FileUploadHelper.ValidateFilesize(uploadedFile, 200);

               if (!filesizeValidationMsg.ResponseStatus)
               {
                   ModelState.AddModelError("FileName", filesizeValidationMsg.ResponseDescription);
               }

               if (content.Format == ResourceFormat.Text)
               {
                   string desiredUploadDirectory = "TextResources";

                   string lesson_file_name = await uploadHelper.SaveFileAsync(Request.Form.Files["FileName"], desiredUploadDirectory).ConfigureAwait(false);

                   existingContent.TextFileUrl = desiredUploadDirectory + "/" + lesson_file_name;
                   existingContent.FileName = lesson_file_name;
                   fileToDelete = existingContent.TextFileUrl;
                   }
                   else
                   {
                      string desiredUploadDirectory = "MultimediaResources";

                      string lesson_file_name = await uploadHelper.SaveFileAsync(Request.Form.Files["FileName"], desiredUploadDirectory).ConfigureAwait(false);

                      existingContent.MultiMediaFileUrl = desiredUploadDirectory + "/" + lesson_file_name;
                      existingContent.FileName = lesson_file_name;
                      fileToDelete = existingContent.MultiMediaFileUrl;
                   }

              }

              existingContent.LastUpdated = DateTime.Now;
              existingContent.Label = content.Label;
              existingContent.Description = content.Description;
              existingContent.LessonId = content.LessonId;
              existingContent.Position = content.Position;
              existingContent.Status = content.Status;
              existingContent.Format = content.Format;
              //_context.Update(existingContent); Now removed for the code to work

              await _context.SaveChangesAsync().ConfigureAwait(false);

              if (fileToDelete != null)
              {
                 System.IO.File.Delete(fileToDelete);
              }
                 return RedirectToAction(nameof(Index));
              }
              catch (Exception e)
              {
                 ModelState.AddModelError("", e.Message);
              }
       }

       ViewData["LessonId"] = new SelectList(_context.Lessons, "Id", "Label", content.LessonId);

       return View(content);
}

But the problem is that when I submit the form for the update, I get the following error message

The instance of entity type 'Content' cannot be tracked because another instance with the same key value for {'Id'} is already being tracked. When attaching existing entities, ensure that only one entity instance with a given key value is attached. Consider using 'DbContextOptionsBuilder.EnableSensitiveDataLogging' to see the conflicting key values.

I do not know how to resolve this. I will appreciate any guide please.

Josh
  • 1,660
  • 5
  • 33
  • 55
  • Possible duplicate of [The instance of entity type cannot be tracked because another instance of this type with the same key is already being tracked](https://stackoverflow.com/questions/36856073/the-instance-of-entity-type-cannot-be-tracked-because-another-instance-of-this-t) – Roman Marusyk Jul 29 '19 at 14:29
  • What is `_context.Update()` ? In most cases, EF will detect which fields need updating automatically. – Neil Jul 29 '19 at 14:37
  • @Neil In my case, I see that it was updating all the records including the ones that did not change, especially the uploaded file record which should only change if there is an uploaded file with the edits – Josh Jul 29 '19 at 14:44
  • What happens if you remove the _context.Update() ? – Neil Jul 29 '19 at 15:10
  • @Neil WoW! it works!!! This seems to be the answer I'm looking for. Please make it an answer so I can accept – Josh Jul 29 '19 at 15:14
  • I thought it might. – Neil Jul 29 '19 at 15:15
  • @Neil It did work, Man! Thank you so much. Hope there is no negative implication to this? – Josh Jul 29 '19 at 15:17
  • EF does a lot of things behind the scenes, so you don't have to think about them. This is one of them. I suspect you read a really old blog about how someone 10 years ago had to do something to get EF to update a record. Remove that `Updated` function from your context, so that no-one else trips up on it. – Neil Jul 29 '19 at 16:04
  • @Neil I have edited my posted code and commented out that line out with remarks. " I suspect you read a really old blog about how someone 10 years ago had to do something to get EF to update a record". That is a really funny but true comment there. Thank you so much anyway. If you add your solution as an answer, I will mark it as the accepted answer – Josh Jul 29 '19 at 17:00

1 Answers1

0

In most cases, EF will automatically detect which fields need updating, having an update function in a context (that takes an entity) is a red flag to say you are trying to do something that is not required.

EF does a lot of things behind the scenes, so you don't have to think about them. This is one of them.

I suspect you read a really old blog about how someone 10 years ago had to do something to get EF to update a record.

Also, remove that update function from your context class, so that no-one else trips up on it.

Neil
  • 11,059
  • 3
  • 31
  • 56