ASP.NET 5 EF 7无法更新数据库表中的条目

时间:2016-02-06 17:22:13

标签: c# asp.net asp.net-mvc entity-framework entity-framework-core

我正在创建一个API,它将启用CRUD功能来创建,读取,更新和删除数据库中的记录。

我遇到了一个问题,即由于共享了一个实例而导致我无法更新表中的条目,我遇到了错误。

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."

这是我的代码:

[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 });
            }
        }

在上面的代码中,您将注意到我首先使用存储库_repository.GetPackageById(Id)获取记录,这允许我验证记录在数据库中,并且我可以使用_repository.UpdatePackage(updatePackage)存储库继续更新。如果我在控制器中注释掉下面的代码,我就可以将数据保存在数据库中。

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

我还确保在启动配置中使用AddScoped,如thread中所述。

services.AddScoped<IAutomationRepository, AutomationRepository>();

我不确定为什么在调用它时不能将多个DBContext实例用于相同的ID。

任何建议都非常感谢。 :)

更新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 :(得分:1)

更改您的存储库方法,如下所示。这可能有所帮助。让我们知道会发生什么

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