ASP.NET 5 EF 7 cannot update entry in database table

asp.net asp.net-mvc c# entity-framework entity-framework-core

Question

I am creating an API that will enable CRUD functionality to Create, Read, Update, and Delete record in database.

I am running into an issue that is not allowing me to update entry inside a table due to an instance is shared and I get below error.

cannot be tracked because another instance of this type with the same key is already being tracked. For new entities consider using an IIdentityGenerator to generate unique key values."

Here is my code:

[HttpPut("{id}")]
        public JsonResult Put(int Id, [FromBody]PackageVersion updatePackage)
        {
            try
            {
                if (ModelState.IsValid)
                {
                    if (updatePackage == null || updatePackage.Id != Id)
                    {
                        Response.StatusCode = (int)HttpStatusCode.BadRequest;
                        return Json(new { status = "Bad Request" });
                    }

                    var package = _respository.GetPackageById(Id);
                    if (package == null)
                    {
                        Response.StatusCode = (int)HttpStatusCode.NotFound;
                        return Json(new { status = "Not Found", Message = package });
                    }

                    _respository.UpdatePackage(updatePackage);
                    if (_respository.SaveAll())
                    {
                        Response.StatusCode = (int)HttpStatusCode.Accepted;
                        return Json(updatePackage);
                    }
                }
                Response.StatusCode = (int)HttpStatusCode.BadRequest;
                return Json(new { status = "Failed", ModelState = ModelState });
            }
            catch (Exception ex)
            {
                Response.StatusCode = (int)HttpStatusCode.BadRequest;
                return Json(new { status = "Failed", Message = ex.Message });
            }
        }

In the above code you will notice I am first getting a record by using repository _repository.GetPackageById(Id), which allows me to validate that a record is in database and I can continue to update by using _repository.UpdatePackage(updatePackage) repository. If I comment out below code in my controller, I am able to save the data in the database.

//var package = _respository.GetPackageById(Id);
//if (package == null)
//{
//    Response.StatusCode = (int)HttpStatusCode.NotFound;
//    return Json(new { status = "Not Found", Message = package });
//}

I also made sure that I was using AddScoped in startup configuration as mentioned in this thread.

services.AddScoped<IAutomationRepository, AutomationRepository>();

I am not sure why I cant use multiple DBContext instances for same ID when it is called.

Any suggestion is really appreciated. :)

UPDATE 1:

public class AutomationRepository : IAutomationRepository
    {
        private AutomationDBContext _context;

        public AutomationRepository(AutomationDBContext context)
        {
            _context = context;
        }

        public void AddPackage(PackageVersion newPackage)
        {
            _context.Add(newPackage);
        }

        public void DeletePackage(int id)
        {
            var package = _context.PackageVersions.SingleOrDefault(p => p.Id == id);
            _context.PackageVersions.Remove(package);
        }

        public IEnumerable<PackageVersion> GetAllPackages()
        {
            return _context.PackageVersions.OrderBy(p => p.PackageName).ToList();
        }

        public object GetPackageById(int id)
        {
            return _context.PackageVersions.SingleOrDefault(p => p.Id == id);
        }

        public bool SaveAll()
        {
            return _context.SaveChanges() > 0;
        }

        public void UpdatePackage(PackageVersion updatePackage)
        {
            _context.Update(updatePackage);
        }
1
0
5/23/2017 10:28:26 AM

Accepted Answer

Change your repository method like below. This may help. Let us know what happens

public object GetPackageById(int id)
{ 
 return _context.PackageVersions.AsNoTracking().SingleOrDefault(p => p.Id ==id);
}
1
2/7/2016 8:18:50 AM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow