Jon-taib
Jon-taib

Reputation: 17

ApplicationUser is not saving changes to field after there is already a value in that field

I'm working on a project that keeps track of the hours employees have worked between different crews. The way the app is supposed to work is that an employee submits a Daysheet form that has their clock-in and clock-out time and the id of their Field Manager(FMId). Each Field Manager has a column in the database that should keep track of the DaysheetIds of forms that are submitted with their FMId. The problem is that this column is only saving the first DaysheetId that gets submitted. Once there's a value in that column, the Field Manager doesn't update to add any other DaysheetIds.

To keep my post concise, I'm trying to post only the relevant code, but let me know if I'm missing something that would be important.

Here's the action in my controller where the Field Manager should be updated. I added the var FM just before the return to see what was happening to the Field Manager with the debugger.

public IActionResult Submit(EmployeeDaySheetViewModel employeeDaySheetViewModel)
        {
            if (ModelState.IsValid)
            {
                var newDaySheet = new EmployeeDaySheet
                {
                    Id = employeeDaySheetViewModel.DaysheetId,
                    EmployeeId = employeeDaySheetViewModel.EmployeeId,
                    EmployeeName = employeeDaySheetViewModel.EmployeeName,
                    FMId = employeeDaySheetViewModel.FMId,
                    Date = employeeDaySheetViewModel.Date,

                    ClockIn = employeeDaySheetViewModel.ClockIn,
                    ClockOut = employeeDaySheetViewModel.ClockOut,
                };
                var success = _employeeDaySheetRepository.AddDaySheet(newDaySheet);
                if (success)
                {
                    _applicationUserRepository
                        .AddCrewDaySheetToFieldManager(employeeDaySheetViewModel.FMId,
                                                        employeeDaySheetViewModel.DaysheetId);
                    TempData["UserMessage"] = "Successfully submitted daysheet for " + DateTime.Now.Day.ToString();
                }
                else
                {
                    TempData["ErrorMessage"] = "Unable to submit daysheet.  Please try again in a few minutes.";
                }

            }
            var FM = _applicationUserRepository.GetFieldManagerById(employeeDaySheetViewModel.FMId);
            return Redirect("/home/");

Here is the AddCrewDaySheetToFieldManager method in my user repository that's being called in the controller action:

public bool AddCrewDaySheetToFieldManager(string FMId, string DaySheetId)
        {
            var fieldManager = _applicationDbContext.ApplicationUsers
                .FirstOrDefault(u => u.Id == FMId);
            if (fieldManager.CrewDaySheetIds != null)
                
                {
                    var oldCrewIds = fieldManager.CrewDaySheetIds;

                    // If the user deletes all their crewIds, the database leaves an empty string in their crewIds column.
                    // Replacing user.crewIds that has "" at index 0 is the same as starting a new list.
                    if (oldCrewIds[0] == "")
                    {
                        var newCrewIds = new List<string> { DaySheetId };
                        fieldManager.CrewDaySheetIds = newCrewIds;
                    }
                    else
                    {
                        fieldManager.CrewDaySheetIds.Add(DaySheetId);
                    }
                }
            else { fieldManager.CrewDaySheetIds = new List<string> { DaySheetId }; }
            _applicationDbContext.SaveChanges();
            return true;

This is what my ApplicationUser looks like:

public class ApplicationUser : IdentityUser
    {
        public string Tier { get; set; }
        public bool IsFieldManager { get; set; }
        public double HourRate { get; set; }

        public string FirstName { get; set; }
        public string LastName { get; set; }

        public List<string> PayrollObjectIds { get; set; }
        public List<string> CrewDaySheetIds { get; set; }

    }

In order to convert the lists attributes of this object to strings, I've got this in my DbContext

protected override void OnModelCreating(ModelBuilder builder)
        {
            var splitStringConverter = new ValueConverter<List<string>, string>(v => string.Join(";", v), v => v.Split(new[] { ';' }).ToList());
            builder.Entity<ApplicationUser>().Property(nameof(ApplicationUser.PayrollObjectIds)).HasConversion(splitStringConverter);
            builder.Entity<ApplicationUser>().Property(nameof(ApplicationUser.CrewDaySheetIds)).HasConversion(splitStringConverter);

            base.OnModelCreating(builder);

           //I also seed some data here//
        }

What I can't figure out is the point at which the data is not getting saved. When I run the debugger, I can see the fieldManager is getting updated. In the AddCrewDaySheetToFieldManager method, fieldManager.CrewDaySheetIds has the DaysheetId. Then, back in the action, just before return Redirect('/home/')the FM.CrewDaySheetIds still has the DaysheetId. However, when I look at the database or try to access the CrewDaysheetIds on the FM user, only the first DaysheetId is there.

I suspect that there's something going wrong with the splitStringConversion, but I've used the same code in another project and not had this issue, so I'm stuck for what to do.

Upvotes: 0

Views: 134

Answers (1)

Hesam Javadi
Hesam Javadi

Reputation: 115

I didn't understand your question correctly but if you want update or insert some data in your database you can use _applicationDbContext.ApplicationUsers.add(fieldManager); for insert, and _applicationDbContext.Entry(fieldManager).State = EntityState.Modeified; for update. but you didn't use any of them before _applicationDbContext.SaveChanges().

I think you have to write this:

    public bool AddCrewDaySheetToFieldManager(string FMId, string DaySheetId)
        {
            var fieldManager = _applicationDbContext.ApplicationUsers
                .FirstOrDefault(u => u.Id == FMId);
            if (fieldManager.CrewDaySheetIds != null)
                
                {
                    var oldCrewIds = fieldManager.CrewDaySheetIds;

                    // If the user deletes all their crewIds, the database leaves an empty string in their crewIds column.
                    // Replacing user.crewIds that has "" at index 0 is the same as starting a new list.
                    if (oldCrewIds[0] == "")
                    {
                        var newCrewIds = new List<string> { DaySheetId };
                        fieldManager.CrewDaySheetIds = newCrewIds;
                    }
                    else
                    {
                        fieldManager.CrewDaySheetIds.Add(DaySheetId);
                    }
                }
            else { fieldManager.CrewDaySheetIds = new List<string> { DaySheetId }; }
            _applicationDbContext.entry(fieldManager).State = EntityState.Modified;
            _applicationDbContext.SaveChanges();
            return true;

Upvotes: 2

Related Questions