0

The key might be assigned, because if its not, then Add will be used, but i don't know how to make it assigned. When i edited the entity instead of editing the new entity was added.

model:

    public class Products
    {
        [Key, NotNull, Required]
        public int ProductId { get; set; }
        [Required, NotNull]
        public string Name { get; set; }    
        public int Price { set; get; }
        public int Quantity { set; get; }
       

    }

controller:

        {
            if (id == null || id == 0)
            {
                return NotFound();
            }
            var productFromDb = _db.Products.Find(id);

            if (productFromDb == null)
            {
                return NotFound();
            }
            return View(productFromDb);
        }
        //post
        [HttpPost]
        [ValidateAntiForgeryToken]
        public IActionResult Edit(Products obj)
        {

            if (ModelState.IsValid)
            {

                _db.Products.Update(obj);   
                _db.SaveChanges();
                return RedirectToAction("Products");
            }
            return View(obj);

        }

`

ruslana
  • 1
  • 1
  • You should use Attach instead https://stackoverflow.com/questions/4218566/update-a-record-without-first-querying – Denys Nov 17 '22 at 22:22
  • Here's documentation https://learn.microsoft.com/en-us/ef/ef6/saving/change-tracking/entity-state#attaching-an-existing-entity-to-the-context – Denys Nov 17 '22 at 22:33

1 Answers1

0

From Microsoft documentation about DbSet.Update() method:

For entity types without generated keys, the state set is always Modified.

Your entity have KeyAttribute withou DatabaseGenerated option defined, this means that entity's table PK column will be created, by default, with IDENTITY property.

This is what "generated keys" means, the Products table will be created with "generated keys" and is because of that that your entity is always INSERTED. EF will always ignore the ProductId value because it will use the IDENTITY automatic generated value when not in "Modified" state.

To avoid that, you have two options:

  • Tell DbContext that your object is on 'Modified' state explicit;
  • Use DatabaseGeneratedAttribute to configure "generated keys" on your entity;

Telling DbContext that the object is on "Modified" state

if (ModelState.IsValid)
{
    _db.Entry(o).State = System.Data.Entity.EntityState.Modified;
    _db.Products.Update(obj);   
    _db.SaveChanges();
    return RedirectToAction("Products");
}

Using DatabaseGeneratedAttribute

public class Products
{
    [Key, NotNull, Required, DatabaseGenerated(DatabaseGeneratedOption.None)]
    public int ProductId { get; set; }
    // ... other properties
}

More info about generated values.

Henryk Budzinski
  • 1,161
  • 8
  • 20