Go Premium for a chance to win a PS4. Enter to Win

x
?
Solved

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

Posted on 2014-10-15
2
Medium Priority
?
2,372 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 Ageil earned 2000 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

Ask an Anonymous Question!

Don't feel intimidated by what you don't know. Ask your question anonymously. It's easy! Learn more and upgrade.

Question has a verified solution.

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

In the first part of this tutorial we will cover the prerequisites for installing SQL Server vNext on Linux.
When trying to connect from SSMS v17.x to a SQL Server Integration Services 2016 instance or previous version, you get the error “Connecting to the Integration Services service on the computer failed with the following error: 'The specified service …
Via a live example, show how to setup several different housekeeping processes for a SQL Server.
Viewers will learn how to use the SELECT statement in SQL to return specific rows and columns, with various degrees of sorting and limits in place.

772 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