0

I am very confused as to why this started happening as I had fixed the problem already. When this problem first occurred I did not have @Html.HiddenFor(model => model.OrganizationID) being passed through the POST action of the form. After I put that in - it worked just fine.

Now, it is not working again. The DbUpdateConcurrencyException is being thrown when I attempt to delete something. My Edit View works just fine.

I followed this tutorial to create a Model first approach.

These are the delete actions in my controller, OrganizationController:

public ActionResult Delete(int id)
{
    using (var db = new VAGTCEntities())
    {
        return View(db.Organizations.Find(id));
    }
}

//
// POST: /Organization/Delete/5

[HttpPost]
public ActionResult Delete(int id, Organization organization)
{
    try
    {
        // TODO: Add delete logic here
        using (var db = new VAGTCEntities())
        {
            db.Entry(organization).State = System.Data.EntityState.Deleted;
            db.SaveChanges();
        }

        return RedirectToAction("Index");

    }
    catch
    {
        return View();
    }
}

This is my delete view:

@model VAGTC.Models.Organization

@{
    ViewBag.Title = "Delete";
}

<h2>Delete</h2>

<h3>Are you sure you want to delete this?</h3>
<fieldset>
    <legend>Organization</legend>

    <div class="display-label">
         @Html.DisplayNameFor(model => model.Name)
    </div>
    <div class="display-field">
        @Html.DisplayFor(model => model.Name)
    </div>
</fieldset>
@using (Html.BeginForm()) {
    @Html.HiddenFor(model => model.OrganizationID)
    <p>
        <input type="submit" value="Delete" /> |
        @Html.ActionLink("Back to List", "Index")
    </p>
}

I debugged it to see if the id is being passed and it is indeed being passed through to the POST action. I am unsure of where to go from here. As anything I search for brings up just adding the HiddenFor statement.

cfisher
  • 235
  • 3
  • 17

1 Answers1

0

This exception indicates that for some reason, no rows were affected by your query (ie. the row was not deleted). Instead of setting the State of the entry, try using the following approach:

db.Remove(organization);
db.SaveChanges();

Edited in response to comments

When you post back the organisation object, it will be populated by the fields contained in the form element of your view. In your case that is only OrganisationId. You change the State of the entity object posted to the controller and save it. If you have set the Concurrency Mode property on any of your EF entities (in the .edmx for example), EF will throw a concurrency exception if the value you pass for that field does not agree with the database value. That could be why it needs the value of the Name field.

A better approach (if you're not concerned about concurrency during deletes) would be to remove the object in the method signature, and rename the Id argument to recieve the OrganisationId. Then read the object directly from the database before setting its state and saving it.

Paul Taylor
  • 5,651
  • 5
  • 44
  • 68
  • I am still getting the same exception. The only thing different I can think of is that I implemented a PagedList. I had to change `@model IEnumerable` – cfisher Nov 11 '12 at 20:34
  • The PagedList collection implements IEnumerable so you can pass it to the existing model definition if it turns out that that's what's causing the problem. You will need to cast the collection to IPagedList to use it with the PagedList helper in the view. (See https://github.com/TroyGoode/PagedList#readme) – Paul Taylor Nov 11 '12 at 20:45
  • That cannot be it. I just switched it all back to the normal list scaffold template, strongly typed to Organization, and `@model IEnumerable – cfisher Nov 11 '12 at 20:53
  • I had to add ~@Html.HiddenFor(model => model.Name)~ to the form as well. I have never had to do this before. It is not the primary key so why would I have to send that as well? – cfisher Nov 11 '12 at 21:14