0
votes

I am trying to update entity but the entity framework do not save changes

this is my code

public bool updateUser(user CUser)
{
            CurrentUser = (CustomPrincipal)HttpContext.Current.User;
            user userToBeUpdated = context.users.Where(user => user.user_id == CurrentUser.Id).FirstOrDefault();

            userToBeUpdated  = CUser;

            context.SaveChanges();
            return true;
}

does there anything wrong in my code?

Update

public bool updateUser(user CUser)
{
    CurrentUser = (CustomPrincipal)HttpContext.Current.User;
    user userToBeUpdated = context.users.Where(user => user.user_id == CurrentUser.Id).FirstOrDefault();
    CUser.user_id = userToBeUpdated.user_id;
    CUser.date_created = userToBeUpdated.date_created;

    if (CUser.Password == "hidden")
        CUser.Password = userToBeUpdated.Password;
    else
        CUser.Password = new Hash().GetBcryptHashedPassword(CUser.Password);

    if (CUser.UDTO.File.ContentLength > 0)
    {
        FileHelper ProfilePicture = new FileHelper(CUser.UDTO.File, "jpg,jpeg,png", 5, true, 500, 500);
        if (!checkUserPersonalImage(CUser.UDTO.File, CUser, ProfilePicture, CurrentUser))
        {
            return false;
        }
        CUser.PersonalImage = ProfilePicture.uploadFile();
    }
    else
    {
        CUser.PersonalImage = userToBeUpdated.PersonalImage;
    }   

    if (!checkRoleValidity(CUser, CurrentUser, false, false))
    {
        return false;
    }
    if (!checkDepartmentValidity(CUser, CurrentUser, false, false))
    {
        return false;
    }
    userToBeUpdated = CUser;
    context.Entry(userToBeUpdated).State = System.Data.Entity.EntityState.Modified;
    context.SaveChanges();
    new UserHelperMethods().updateUserHolderLists(CurrentUser.Company, CUser);
    CUser.UDTO.RedirectTo = "AddNewUser";
    CUser.UDTO.Message="<div class='success'>User has been updated successfully</div>";
    CUser.UDTO.Company = CurrentUser.Company;
    return true;
}

this is the complete function and I got the following error

Attaching an entity of type 'workflow.Models.user' failed because another entity of the same type already has the same primary key value. This can happen when using the 'Attach' method or setting the state of an entity to 'Unchanged' or 'Modified' if any entities in the graph have conflicting key values. This may be because some entities are new and have not yet received database-generated key values. In this case use the 'Add' method or the 'Added' entity state to track the graph and then set the state of non-new entities to 'Unchanged' or 'Modified' as appropriate.

1
welp. your function does not return anything. you probaby skipped something important. Is any exception thrown? - DevilSuichiro
I just noticed.... your function does virtually nothing besides fetch data from the database... - DevilSuichiro
@DevilSuichiro no exceptions - Mo Haidar
userToBeUpdated = CUser; doesn't do what you think it does. - Claies
@Claies I used to update a field in the entity by changing its value and then call the` context.SaveChanges()` for example userToBeUpdated.X = 15; context.SaveChanges(); and then it saves the changes so I think that userToBeUpdated = CUser changes works the same like userToBeUpdated .X = 15; - Mo Haidar

1 Answers

3
votes

I used to update a field in the entity by changing its value and then call thecontext.SaveChanges() for example userToBeUpdated.X = 15; context.SaveChanges(); and then it saves the changes so I think that userToBeUpdated = CUser changes works the same like userToBeUpdated .X = 15

You are quite wrong in assuming that userToBeUpdated.X=15 and userTobeUpdated=CUser does the same thing. The original object that the userToBeUpdated variable referenced is still tracked by EF. After that you change the reference of the userToBeUpdated variable to an instance of another object and attach it to the DbContext. The dbcontext now tries to track two objects: the user it retrieved from the database and a second object that has the same primary key. EF balks at that and throws an exception.

So the .X=15 approach is the correct one. You should update all relevant properties on the userToBeUpated from CUser and then save changes.