Tuesday 30 April 2013

MVC 4 - How to edit multiple records at once

This example shows how to perform bulk edit of records
I am using FormCollection for this purpose.

Watch this example on YouTube:







I will be editing FirstName and LastName in table above.(Please ignore DepartmentID column, I am not going to use it in this tutorial)  For that purpose I will create EF connection to the database (step by step examples in other MVC tutorials or in the video above) and will modify my View
@model IEnumerable<TestMultiUpdateWithMVC.Models.User>

@{
    ViewBag.Title = "Index";
}

<h2>Index</h2>

@using (Html.BeginForm()){
<table>
    @Html.ValidationSummary(true)
    <tr>
        <th>
            @Html.DisplayNameFor(model => model.FirstName)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.LastName)
        </th>
        <th></th>
    </tr>

@foreach (var item in Model) {
    <tr>
        <td>
            @Html.HiddenFor(modelItem => item.UserId)
        </td>
        <td>
            @Html.EditorFor(modelItem => item.FirstName)
            @Html.ValidationMessageFor(model => item.FirstName)
        </td>
        <td>
            @Html.EditorFor(modelItem => item.LastName)
            @Html.ValidationMessageFor(model => item.LastName)
        </td>
    </tr>
}

</table>
<input type="submit" value="save" />
}

So it produces page that presents all users with Save button



Now I will add the following code to the controller
        [HttpPost]
        public ActionResult Index(FormCollection c)
        {
            int i = 0;
            if (ModelState.IsValid)
            {
                var UserIDArray = c.GetValues("item.UserId");
                var UserFirstNameArray = c.GetValues("item.FirstName");
                var UserLastNameArray = c.GetValues("item.LastName");

                for (i = 0; i < UserIDArray.Count(); i++)
                {
                    User usr = db.Users.Find(Convert.ToInt32(UserIDArray[i]));
                    usr.FirstName = UserFirstNameArray[i];
                    usr.LastName = UserLastNameArray[i];
                    db.Entry(usr).State = EntityState.Modified;
                }
                db.SaveChanges();
            }
            return View(db.Users.ToList());
        }

That's it!  - Since I know that all arrays will have the same size, I can load all values to my arrays, then update my user(s).










8 comments:

  1. Great example...thanks...but, of course, my requirements are a bit different...do you have a suggestion for this... I have 2 tables (car and truck for example) and each has a KEY id. A third table (owner for example) has a KEY id also. The owner.id is a foreign key for both car and truck...so an owner can have any number (0 or more) cars and any number of (0 or more) trucks. I want to find all the cars and trucks for owner.id = 2 and EDIT them on one FORM (similar to your example).
    What do you think? Thanks much, Ron

    ReplyDelete
  2. God bless you! I have been trying to get this to work for a few days now and your example worked perfectly. Thank you very much.

    ReplyDelete
  3. wonderful example, i have a one problem in validation message , if someone missing to enter one of first name all fields shows error message . i think its because of loop .
    How can i show validation message for only that field .
    thank you

    ReplyDelete
  4. I think I've done this with javascript (loop through all elements), I can't find my code though, if I find it, I will post it. Or maybe someone else can propose better solution?

    ReplyDelete
  5. User usr = db.Users.Find(Convert.ToInt32(UserIDArray[i]));

    What does your db in this stand for? Am using code first I do not have any database yet.

    ReplyDelete
  6. What would you do if your db has like thousands items and you only make change to only a small number (or even 1) of items? Do you really have to loop through all items?

    ReplyDelete
  7. I'm very grateful, this article helped me in my work.

    ReplyDelete