Home > database >  ASP.NET Core error : database operation expected to affect 1 row(s) but actually affected 0 row(s)
ASP.NET Core error : database operation expected to affect 1 row(s) but actually affected 0 row(s)

Time:06-21

I have a problem and I tried to solve it a lot, which is when I want to modify the user data by the function EditOrCreateInformation() this error exception message appears:

Microsoft.EntityFrameworkCore.DbUpdateConcurrencyException: 'Database operation expected to affect 1 row(s) but actually affected 0 row(s). Data may have been modified or deleted since entities were loaded.

Screenshot of the error is display here

Controller code:

[HttpPost]
public IActionResult EditOrCreateInformation(ApplicationUserVm model, ApplicationUser user)
{
    if (ModelState.IsValid)
    {
        var olddata = context.Users.Where(a => a.Id == user.Id).AsNoTracking().FirstOrDefault();
        string oldfilename = olddata.PhotoUrl;

        if (model.Photo == null)
        {
            model.PhotoUrl = oldfilename;
        }

        if (oldfilename != null)
        {
            if (model.Photo != null && System.IO.File.Exists(Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "PhotoFiles/PhotoProfile", oldfilename)))
            {
                System.IO.File.Delete(Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "PhotoFiles/PhotoProfile", oldfilename));
                string PhysicalPath = Path.Combine(Directory.GetCurrentDirectory()   "/wwwroot", "PhotoFiles/PhotoProfile/");
                // 2) Get File Name
                string FileName = Guid.NewGuid()   Path.GetFileName(model.Photo.FileName);
                // 3) Merge Physical Path   File Name
                string FinalPath = Path.Combine(PhysicalPath, FileName);

                // 4) Save The File As Streams "Data Over Time"
                using(var stream = new FileStream(FinalPath, FileMode.Create))
                {
                    model.Photo.CopyTo(stream);
                }

                model.PhotoUrl = FileName;
            }
        }
        else
        {
            string PhysicalPath = Path.Combine(Directory.GetCurrentDirectory()   "/wwwroot", "PhotoFiles/PhotoProfile/");
            // 2) Get File Name
            string FileName = Guid.NewGuid()   Path.GetFileName(model.Photo.FileName);
            // 3) Merge Physical Path   File Name
            string FinalPath = Path.Combine(PhysicalPath, FileName);

            // 4) Save The File As Streams "Data Over Time"
            using(var stream = new FileStream(FinalPath, FileMode.Create))
            {
                model.Photo.CopyTo(stream);
            }

            model.PhotoUrl = FileName;
        }

        var obj = mapper.Map < ApplicationUser > (model);
        applicationUser.Update(obj);

        toastNotification.AddSuccessToastMessage("Your Information Updated successfully");

        return RedirectToAction("MyProfile", "Profile", new
        {
            Area = "Identity"
        });
    }

    return View(model);
}

Repository code:

public ApplicationUser Update(ApplicationUser obj)
{
    db.Entry(obj).State = EntityState.Modified;
    db.SaveChanges();
    return db.Users.Where(a => a.Id == obj.Id).FirstOrDefault();
}

How can I fix this?

I will be very grateful to help me solve this problem.

CodePudding user response:

You have two issues here.

  • using AsNoTracking
  • using different DbContext

First, The AsNoTracking should be only used on read-only queries aka SELECT. If you need to UPDATE the same object, then you should select the object without using AsNoTracking.

Secondly, Update method you pass the modified User object to a different context that does not have the current object's change tracking history. So, when SaveChanges executed, it won't see any changes; because the object's changes were made in a different context.

so what you need to do is just remove AsNoTracking and replace these lines :

var obj = mapper.Map < ApplicationUser > (model);
applicationUser.Update(obj);

with this :

olddata.PhotoUrl = model.PhotoUrl;
context.Entry(olddata).State = EntityState.Modified;
db.SaveChanges();
  • Related