Solved

Store update, insert, or delete statement affected an unexpected number of rows (0).

Posted on 2014-10-15
2
1,875 Views
Last Modified: 2014-10-18
Hi:

I have an application in which I have used the MVC Scaffolding to create and edit products.  The code works fine for creating and displaying products but when I try to edit the product, I get the following error:

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.

The model for the product is as follows:

[Bind(Exclude = "ProductId")]
    public class Product
    {
        [ScaffoldColumn(false)]
        public int ProductId { get; set; }

        [Required(ErrorMessage = "A Product Title is required")]
        [StringLength(160)]
        public string Title { get; set; }

        [Required(ErrorMessage = "Price is required")]
        [Range(0.00, 100.00,
            ErrorMessage = "Price must be between 0.00 and 100.00")]
        public decimal Price { get; set; }

        public string Description { get; set; }

        [DisplayName("Big Pic URL")]
        [StringLength(1024)]
        public string BigPicUrl { get; set; }

        [DisplayName("Small Pic URL")]
        [StringLength(1024)]
        public string SmallPicUrl { get; set; }

        
        public string ProductTypeCode { get; set; }
        public virtual ProductType ProductType { get; set; }

       
        public string ProductMakerCode { get; set; }
        public virtual ProductMaker ProductMaker { get; set; }
    }

 public class ProductMaker
    {
        [Key]
        [StringLength(8)]
        public string ProductMakerCode { get; set; }

        [DisplayName("Made By")]
        [StringLength(50)]
        public string Name { get; set; }
    }

 public class ProductType
    {

        [Key]
        [StringLength(8)]
        public string ProductTypeCode { get; set; }

        [StringLength(50)]
        [DisplayName("Type")]
        public string Name { get; set; }

        public string Description { get; set; }
        public List<Product> Products { get; set; }

    }

Open in new window


The scaffolded code in the controller from MVC looks like this:
 public ActionResult Edit(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            Product product = db.Products.Find(id);
            if (product == null)
            {
                return HttpNotFound();
            }
            ViewBag.ProductMakerCode = new SelectList(db.ProductMakers, "ProductMakerCode", "Name", product.ProductMakerCode);
            ViewBag.ProductTypeCode = new SelectList(db.ProductTypes, "ProductTypeCode", "Name", product.ProductTypeCode);
            return View(product);
        }

        // POST: Products/Edit/5
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Edit(Product product)
        {
            if (ModelState.IsValid)
            {
                db.Entry(product).State = EntityState.Modified;
                db.SaveChanges();
                return RedirectToAction("Index");
            }
            ViewBag.ProductMakerCode = new SelectList(db.ProductMakers, "ProductMakerCode", "Name", product.ProductMakerCode);
            ViewBag.ProductTypeCode = new SelectList(db.ProductTypes, "ProductTypeCode", "Name", product.ProductTypeCode);
            return View(product);
        }

Open in new window


And the cshtml file is as follows:

@using (Html.BeginForm())
{
    @Html.AntiForgeryToken()
    
    <div class="form-horizontal">
        <h4>Product</h4>
        <hr />
        @Html.ValidationSummary(true, "", new { @class = "text-danger" })
        <div class="form-group">
            @Html.LabelFor(model => model.Title, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.Title, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.Title, "", new { @class = "text-danger" })
            </div>
        </div>

abbreviated...
        <div class="form-group">
            @Html.LabelFor(model => model.ProductTypeCode, "ProductTypeCode", htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.DropDownList("ProductTypeCode", null, htmlAttributes: new { @class = "form-control" })
                @Html.ValidationMessageFor(model => model.ProductTypeCode, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.ProductMakerCode, "ProductMakerCode", htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.DropDownList("ProductMakerCode", null, htmlAttributes: new { @class = "form-control" })
                @Html.ValidationMessageFor(model => model.ProductMakerCode, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Save" class="btn btn-default" />
            </div>
        </div>
    </div>
}

<div>
    @Html.ActionLink("Back to List", "Index")
</div>

Open in new window


Any suggestions on what to do to avoid this error greatly appreciated.

RBS
0
Comment
Question by:RBS
2 Comments
 
LVL 27

Accepted Solution

by:
Sammy earned 500 total points
ID: 40382913
In your Edit Action you should get the record first before attempting to save.
see my comment below as I am not sure what Entry refers to in your code
[HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Edit(Product product)
        {
            if (ModelState.IsValid)
            {
//You need to either attach or select the product first  before setting its state to Modified.
                db.Entry(product).State = EntityState.Modified;
                db.SaveChanges();
                return RedirectToAction("Index");
            }
            ViewBag.ProductMakerCode = new SelectList(db.ProductMakers, "ProductMakerCode", "Name", product.ProductMakerCode);
            ViewBag.ProductTypeCode = new SelectList(db.ProductTypes, "ProductTypeCode", "Name", product.ProductTypeCode);
            return View(product);
        }

Open in new window

more about attach method in EF can be found here http://msdn.microsoft.com/en-us/data/jj592676.aspx
0
 

Author Closing Comment

by:RBS
ID: 40388959
Thanks Sammy - appreciate the link to EF as well

RBS
0

Featured Post

Master Your Team's Linux and Cloud Stack

Come see why top tech companies like Mailchimp and Media Temple use Linux Academy to build their employee training programs.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Batch file or script with password 22 43
SQL Server Designer 19 40
SQL Error - Query 6 25
New to SSRS, extremely slow running report. 8 20
Slowly Changing Dimension Transformation component in data task flow is very useful for us to manage and control how data changes in SSIS.
This article aims to explain the working of CircularLogArchiver. This tool was designed to solve the buildup of log file in cases where systems do not support circular logging or where circular logging is not enabled
Via a live example, show how to extract information from SQL Server on Database, Connection and Server properties
Via a live example, show how to extract insert data into a SQL Server database table using the Import/Export option and Bulk Insert.

770 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question