Search code examples
c#asp.net-mvcapidatacontext

ASP.NET How to update a record without manually setting each property?


What if I have an object with a 100 properties that changed?

This would be horrible to code and prone to missing some properties.

Is there a different way of updating a record than to do it manually?

ApplicationUser CurrentUser = db.Users.FirstOrDefault(x => x.Id == model.Id);

CurrentUser.FirstName = model.FirstName;
CurrentUser.LastName = model.LastName;
CurrentUser.IsRSM = model.IsRSM;
CurrentUser.PhoneNumber = model.PhoneNumber;
CurrentUser.Email = model.Email;
CurrentUser.UserName = model.Email;
CurrentUser.Region = model.Region;
CurrentUser.Active = model.Active;

db.Entry(CurrentUser).State = System.Data.Entity.EntityState.Modified;
db.SaveChanges();

Solution

  • As per comment, here are two ways you can do this programatically:

    Reflection

    var CurrentUser = db.Users.FirstOrDefault(x => x.Id == model.Id);
    
    PropertyInfo[] sourceProps = model.GetType()
        .GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.GetProperty);
    
    PropertyInfo[] targetProps = CurrentUser.GetType()
        .GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.SetProperty);
    
    foreach (var prop in sourceProps)
    {
        var targetProp = targetProps.FirstOrDefault(x => x.Name == prop.Name);
        if (targetProp != null)
            targetProp.SetValue(CurrentUser, prop.GetValue(model));
    }
    
    db.Entry(CurrentUser).State = EntityState.Modified;
    db.SaveChanges();
    

    AutoMapper

    First create map on application startup:

    cfg.CreateMap<ApplicationUserViewModel, ApplicationUser>();
    

    Then execute the map:

    _mapper.Map<ApplicationUserViewModel, ApplicationUser>(model, CurrentUser)