-1

I'm working with C# .NET Framework and I need to know how can I validate all fields that I need to update, for example, I have a table with four fields, so, if the user only have to change a field, how can I update only that field, actually I have this code:

public async Task<ServiceResponse<User>> UpdateUser(User newUserUpdate)
    {
        ServiceResponse<User> serviceResponse = new();

        //Este llamada es para buscar por medio del ID ingresado por el usuario
        User userFinded = await _dataContext.Users.FindAsync(newUserUpdate.Id);

        //¿Como iterar para validar que campos actualizar?

        if (newUserUpdate.userName != null) userFinded.userName = newUserUpdate.userName;
        if (newUserUpdate.email != null) userFinded.email = newUserUpdate.email;
        if (newUserUpdate.password != null) userFinded.password = newUserUpdate.password;

        _dataContext.Users.Update(userFinded);
        _dataContext.SaveChanges(); 
        serviceResponse.Message = "Usuario Actualizado Exitosamente";

        return serviceResponse;
    }

I´m using IF sentence to validate and update the new value, but I think that is not a good practice. Maybe is a lambda expression?

Robert Harvey
  • 178,213
  • 47
  • 333
  • 501
  • 3
    Remove `_dataContext.Users.Update(userFinded);` and it will work as expected. – Svyatoslav Danyliv May 24 '21 at 14:38
  • @SvyatoslavDanyliv if OP removes `_dataContext.Users.Update(userFinded);` then there will be no changes to save. – Nicholas Hunter May 24 '21 at 15:02
  • @NicholasHunter why? OP take entity from context. Make changes. And call `Save` – demo May 24 '21 at 15:07
  • @NicholasHunter, you have to learn EF again. There is no need to call `Update` to update entity in database. Change Tracker will detect that new values of object is different than after `FindAsync` call and automatically update only needed fields. – Svyatoslav Danyliv May 24 '21 at 15:13

1 Answers1

0

You do not need to call _dataContext.Users.Update(userFinded); explicitly. EF will detect changes in your object automatically and update only needed fields. So just call SaveChanges for DbContext and ChangeTracker will find which properties are changed.

From other side, EF's CRUD scenario is not optimal for performance. Here you have two database roundtrips and you have to cover them explicitly in transaction: FindAsync and SaveChanges.

Not so "cute" but effective is to use detached entity:

public async Task<ServiceResponse<User>> UpdateUser(User newUserUpdate)
{
    ServiceResponse<User> serviceResponse = new();

    if (newUserUpdate.userName != null) ||
        newUserUpdate.email    != null) ||
        newUserUpdate.password != null)
    {
        _dataContext.Users.Attach(newUserUpdate);
        var entry = _dataContext.Entry(newUserUpdate);

        if (newUserUpdate.userName != null) entry.Property(x => x.userName).IsModified = true;
        if (newUserUpdate.email    != null) entry.Property(x => x.email).IsModified = true;
        if (newUserUpdate.password != null) entry.Property(x => x.password).IsModified = true;

        await _dataContext.SaveChangesAync();
    }

    serviceResponse.Message = "Usuario Actualizado Exitosamente";

    return serviceResponse;
}
Svyatoslav Danyliv
  • 21,911
  • 3
  • 16
  • 32