CloudyKooper
CloudyKooper

Reputation: 717

Why is my code not able to update the database?

I am having trouble saving my entities after updating them. I can add new entities like this: add(student); but if I tried this:

if (ModelState.IsValid)
{
   db.Entry(student).State = EntityState.Modified;
   db.SaveChanges();
   return RedirectToAction("someView");
}

I get this error message:

System.Data.Entity.Infrastructure.DbUpdateConcurrencyException was unhandled by user code
Message=Store update, insert, or delete statement affected an unexpected number of rows (0). Entities may have been modified or deleted since entities were loaded. Refresh ObjectStateManager entries.

Here’s my controller method:

[HttpPost]
public ActionResult ClassAttendance(InstructorIndexData viewModel, FormCollection frmcol)
{
     var instructorData = new InstructorIndexData();

     string[] AllFstMNames = frmcol["item.Student.FirstMidName"].Split(',');
     string[] AllLstNames = frmcol["item.Student.LastName"].Split(',');
     string[] AllAddresses = frmcol["item.Student.Address"].Split(',');
     string[] AllEnrollmentDates = frmcol["item.Student.EnrollmentDate"].Split(',');
     //more of the same code…

     var student = new Student();
     var enrollment = new Enrollment();

     for ( int i = 0; i < AllFstMNames.Count(); i++)
     {
         student.FirstMidName = AllFstMNames[i];
         student.LastName = AllLstNames[i];
         student.Address = AllAddresses[i];
         student.EnrollmentDate = Convert.ToDateTime(AllEnrollmentDates[i]);

         if (!string.IsNullOrEmpty(frmcol["item.Grade"]))
         {
            enrollment.Grade = Convert.ToInt32(AllGrades[i]);
         }

         enrollment.StudentID = Convert.ToInt32(AllStudentIds[i]);
         enrollment.attendanceCode = Convert.ToInt32(AllAttendanceCodes[i]);
         enrollment.classDays = AllclassDays[i];
         enrollment.CourseID = Convert.ToInt32 (AllCourseIds[i]);
         //update rows
      }

      if (ModelState.IsValid)
      {
         db.Entry(student).State = EntityState.Modified;
         db.SaveChanges();
         return RedirectToAction("someView");
      }

Can you help me with just being able to update values in the database?

Upvotes: 1

Views: 1848

Answers (1)

TLS
TLS

Reputation: 3150

While I was looking at the code here, my initial thought is that it doesn't seem quite right to have a for loop that updates the student and enrollment objects multiple times and then to have only one call to db.SaveChanges outside the loop. This is concerning because only the last iteration of the for loop will be applied when the data is saved to the database. (You have a comment to "update rows" at the end of the for loop - perhaps some code is missing or misplaced?)

Then, I started thinking about why it would be necessary to manually set the Entry(...).State property. Wouldn't the db automatically know that an object is modified and needs to be saved? That lead me to this question: Where is db defined? What technology stack is being used there?

Finally, after making an assumption that the db object might work something like the MS LINQ-to-SQL feature, I noticed that the the student object is newly instantiated before the for loop. This is fine for inserting new data, but if you are wanting to update existing data, I believe you need to first get a copy of the object from the database and then update the properties. This allows the db object to monitor the changes (again, assuming that it has this capability). (If this is not the case, then it leads me to wonder how the db will know which record in the database to update since you are not setting anything that appears to be a primary key, such as StudentId, on the student object in the loop.)

Upvotes: 2

Related Questions