dondomates
dondomates

Reputation: 55

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

I try to update my Products table but i can't because throw an error.

This is my hardcode controller:

[HttpPost]
public ActionResult EditProduct(ProductsViewModel productViewModel)
{
    TechStoreEntities context = new TechStoreEntities();

    Product newProduct = new Product
    {
        ProductId = productViewModel.ProductId,
        Name = productViewModel.Name,
        Price = productViewModel.Price,
        Discount = productViewModel.Discount,
        Quantity = productViewModel.Quantity,
        Size = productViewModel.Size,
        Description = productViewModel.Description,
        ProducerName = productViewModel.ProducerName,
        PaymentMethods = productViewModel.PaymentMethods,
        CategoryID = productViewModel.CategoryID,
        SubcategoryID = productViewModel.SubcategoryID,
        IsNew = productViewModel.IsNew,
        IsEnable = productViewModel.IsEnable
    };

    context.Entry(newProduct).State = EntityState.Modified;
    context.SaveChanges();

    ViewBag.CategoryID = new SelectList(context.Categories.Where(c => c.SubCategoryID == null), "CategoryID", "Name");
    ViewBag.SubcategoryID = new SelectList(context.Categories.Where(c => c.SubCategoryID != null), "CategoryID", "Name");

    return RedirectToAction("Products");
}

This is a model:

public class ProductsViewModel
{
    public int ProductId { get; set; }
    public string Name { get; set; }
    public int Price { get; set; }
    public int Discount { get; set; }
    public int Quantity { get; set; }
    public string Size { get; set; }
    public string Description { get; set; }
    public string ProducerName { get; set; }
    public string PaymentMethods { get; set; }
    public bool IsNew { get; set; }
    public bool IsEnable { get; set; }
    public string Category { get; set; }
    public int CategoryID { get; set; }
    public string Subcategory { get; set; }
    public int SubcategoryID { get; set; }
    public DateTime? CreateDate { get; set; }
}

I use strongly typed view:

@model MyTechStore.Models.ProductsViewModel

I add in a view:

@Html.HiddenFor(model => model.ProductId)

When i start app and enter some data to update existing data and press save, throw me exception:

System.Data.Entity.Infrastructure.DbUpdateConcurrencyException

When i debugging i saw that only the ProductId was 0. Everything else is OK. I tested with scaffolding controller but there is OK. I want to use view model, not as scaffolding controller use the model from my database.

Can someone tell me where i'm wrong?

My GET method:

public ActionResult EditProduct(int? id)
{
    TechStoreEntities context = new TechStoreEntities();

    ProductsManipulate product = new ProductsManipulate();

    ProductsViewModel editProduct = product.EditProduct(id);

    ViewBag.CategoryID = new SelectList(context.Categories.Where(c => c.SubCategoryID == null), "CategoryID", "Name");
    ViewBag.SubcategoryID = new SelectList(context.Categories.Where(c => c.SubCategoryID != null), "CategoryID", "Name");
    return View(editProduct);
}

And my data access layer:

public ProductsViewModel EditProduct(int? id)
{
    TechStoreEntities context = new TechStoreEntities();
    Product dbProduct = context.Products.Find(id);
    ProductsViewModel product new ProductsViewModel
    {
        Name = dbProduct.Name,
        Price = dbProduct.Price,
        Quantity = dbProduct.Quantity,
        CategoryID = dbProduct.CategoryID,
        SubcategoryID = dbProduct.SubcategoryID,
        IsNew = dbProduct.IsNew
    };
    return product;
}

Upvotes: 2

Views: 207

Answers (2)

Rick Su
Rick Su

Reputation: 16440

You need to populate ProductId in ProductsViewModel

public ProductsViewModel EditProduct(int? id)
{
    TechStoreEntities context = new TechStoreEntities();

    Product dbProduct = context.Products.Find(id);

    ProductsViewModel product = new ProductsViewModel()
    {
        // You need this line to pass the value to View
        ProductId = dbProduct.ProductId,

        Name = dbProduct.Name,
        Price = dbProduct.Price,
        Quantity = dbProduct.Quantity,
        CategoryID = dbProduct.CategoryID,
        SubcategoryID = dbProduct.SubcategoryID,
        IsNew = dbProduct.IsNew
    };

    return product;
}

Upvotes: 3

Michal Ciechan
Michal Ciechan

Reputation: 13888

What that error is saying, is that EF tried to update a Product with those fields, but the it returned 0 RowCount therefore it knows something went wrong.

As you have mentioned before, the ProductId is 0, meaning you probably don't have a Product with that ID, and therefore when EF tries to update it, the row count is 0, which causes EF to throw a DbUpdateConcurrencyException.

You need to make sure your Id is populated if you want to an update an existing product.

Otherwise if you want an upsert (Update or Insert) you first need to check if a record exists for your given ProductId and if it does, do update, otherwise do insert.

Upvotes: 1

Related Questions