Search code examples
c#entity-frameworkoptimistic-concurrency

ASP.NET MVC OptimisticConcurrencyException


I am trying to write to two tables in my database in a function that takes in lists as a parameter from the previous page. I call the db to retrieve the purchase_order_no because the column is an IDENTITY primary key that is generated on entry.

Models:

purchase_order

    [Key]
    [Column(Order = 0)]
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public int client_no { get; set; }

    [Key]
    [Column(Order = 1)]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int purchase_order_no { get; set; }

    [StringLength(60)]
    public string name { get; set; }

    [Key]
    [Column(Order = 2)]
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public int order_group_no { get; set; }

    [StringLength(24)]
    public string purchase_order_reference { get; set; }

    [Key]
    [Column(Order = 3)]
    public DateTime order_timestamp { get; set; }

order_detail

    [Key]
    [Column(Order = 0)]
    public long order_detail_no { get; set; }

    [Key]
    [Column(Order = 1)]
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public int purchase_order_no { get; set; }

    [Key]
    [Column(Order = 2)]
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public int inventory_no { get; set; }

    [Key]
    [Column(Order = 3)]
    public decimal quantity { get; set; }

    public int? vendor_no { get; set; }

I receive this error when trying to insert my new 'purchase_order' model into the db:

Store update, insert, or delete statement affected an unexpected number of rows (0). Entities may have been modified or deleted since entities were loaded. See http://go.microsoft.com/fwlink/?LinkId=472540 for information on understanding and handling optimistic concurrency exceptions.

    [HttpPost]
    public ActionResult orderForm (List<int> quantity, List<string> itemName, List<int> inventory_no, List<int> client_no, List<int> vendorCode, int orderGroupNo)
    {
        using (var db = new db_model())
        {
            var ctx = ((IObjectContextAdapter)db).ObjectContext;
            purchaseOrderVM poVM = new purchaseOrderVM();
            List<order_detail> tempList = new List<order_detail>();
            purchase_order po = new purchase_order();
            po.client_no = client_no[0];
            var purchaseOrder = db.purchase_order.Where(x => x.client_no == po.client_no).Max(x => x.purchase_order_no);
            po.order_group_no = orderGroupNo;
            po.order_timestamp = DateTime.Now;
            db.purchase_order.Add(po);
            try
            {
                db.SaveChanges(); <!-- This is where I get the error -->
            }
            catch (OptimisticConcurrencyException e)
            {
                ctx.Refresh(RefreshMode.ClientWins, db.purchase_order);
                throw e;

            }
            for (int i = 0; i < itemName.Count(); i++)
            {
                order_detail od = new order_detail();
                od.purchase_order_no = db.purchase_order.Where(x => x.client_no == po.client_no).Max(x => x.purchase_order_no);
                od.inventory_no = inventory_no[i];
                od.quantity = quantity[i];
                od.vendor_no = vendorCode[i];
                db.order_detail.Add(od);
                try
                    {
                        db.SaveChanges();
                    }
                catch (OptimisticConcurrencyException e)
                    {
                        ctx.Refresh(RefreshMode.ClientWins, db.order_detail);
                        throw e;
                    }
                tempList.Add(od);
            }
            poVM.purchase_order = po;
            poVM.orderList = tempList;
            return View(poVM);

        }
    }

Solution

  • I think the problem is in your model class. In purchase_order, why do you have so many columns flagged as [Key]? As purchase_order_no is declared as an identity column, it should be the primary key by itself. I don't even know why EF doesn't complain at startup, because your configuration makes no sense.

    Remove the [Key] attribute on all other columns, and it should work. If you need to ensure uniqueness, you can create a unique index on the other columns.