Search code examples
c#asp.netinsert-update

C# SetValues, EntityState.Modified not working


I have the following entries in my database:

MeetingID   AgendaItem  LegistarID  Title
48620       3           60710       Comment
48620       5           60615       Extending report date
48620       6           60714       Update on Additional meeting dates
48620       7           59909       Budget Rules & Procedures
48620       8           60703       Update Director name

That I need to update with these values:

MeetingID   AgendaItem  LegistarID  Title
48620       3           60710       Public Comment
48620       5           60769       Briefing by Victor
48620       6           60615       Extending report dates
48620       7           60714       Update on Additional meeting dates
48620       8           60703       Update from Director on new processes

The way I am trying doing this in C#, is as follows:

if (ModelState.IsValid)
{
    var errors = new List<string>();
    var rowCounter = 1;

    using (Entities db = new Entities())
    {
        foreach (var i in meeting)
        {
            if (i.MeetingID == 0)
            {
                // Let the user know this row is bad 
                errors.Add($"Row {rowCounter}: Missing Meeting ID value. " +
                            "Verify that the data you are trying to upload meets the required criteria, " +
                            "and then try to upload your file again." );
                break;
            }
            // Check if LegistarID is missing
            if (i.LegistarID == 0)
            {
                // Check if Agenda Item is present
                if (i.AgendaItem == 0)
                {
                    errors.Add($"Row {rowCounter}: Meeting has no LegistarID and no Agenda Item. Please check data.");
                    break;
                }
                else
                {
                    i.LegistarID = i.AgendaItem;
              }
            }

            var compositeKey = db.Meeting.Find(i.MeetingID, i.AgendaItem);

            if (compositeKey == null)
            {

                // Add new
                db.Meeting.Add(i);

            }
            else
            {
                // Serves as an update, or addition of a previously imported dataset
                db.Entry(compositeKey).CurrentValues.SetValues(i.MeetingID);
                db.Entry(compositeKey).CurrentValues.SetValues(i.AgendaItem);
                db.Entry(compositeKey).CurrentValues.SetValues(i.LegistarID);
                db.Entry(compositeKey).CurrentValues.SetValues(i.Title);
                db.Entry(compositeKey).State = EntityState.Modified;
            }
            rowCounter++;
        }
        // If there are errors do not save and return error message
        if (errors.Count > 0)
        {
            return new JsonResult { Data = new { status = false, message = string.Join("\n", errors) } };
        }
        db.SaveChanges();
        status = true;
    }
}
else
{
    message = string.Format(@"Please, verify that the file you are trying to upload is correctly formatted, 
                            and that the data it contains, meets the expected criteria, 
                            then click the upload button again. \n Thank you!");
    return new JsonResult { Data = new { status = status, message = message } };
}

The code for the Add part works well, but the part that updates the record if the composite key is found does not work, the update is not working.

I am not sure if I am doing this the best way, but if there is a better way I am open to change the code, or if I have an error on how I am doing the process, please let me know

Any help is appreciated.

Thank you, Erasmo


Solution

  • Remove all your calls to SetValues and replace them with single one:

    db.Entry(compositeKey).CurrentValues.SetValues(i);
    

    SetValues which accepts object as parameter copies data to entity based on object properties names:

    Any property on the object with a name that matches a property name in the entity type and can be read will be copied. Other properties will be ignored.