Solved

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

Posted on 2014-10-15
2
2,097 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
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

Get 15 Days FREE Full-Featured Trial

Benefit from a mission critical IT monitoring with Monitis Premium or get it FREE for your entry level monitoring needs.
-Over 200,000 users
-More than 300,000 websites monitored
-Used in 197 countries
-Recommended by 98% of users

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.
It is possible to export the data of a SQL Table in SSMS and generate INSERT statements. It's neatly tucked away in the generate scripts option of a database.
Using examples as well as descriptions, and references to Books Online, show the different Recovery Models available in SQL Server and explain, as well as show how full, differential and transaction log backups are performed
Via a live example, show how to setup several different housekeeping processes for a SQL Server.

624 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