【发布时间】:2016-05-16 14:26:38
【问题描述】:
我正在创建一个 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>();
我不确定为什么在调用同一 ID 时我不能使用多个 DBContext 实例。
非常感谢任何建议。 :)
更新 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);
}
【问题讨论】:
-
为什么不使用作用域上下文而不是使用多个?
-
你的意思是
_context.TableName? -
也许吧。向我们展示存储库的实施。
-
在我的原始帖子中添加了更新 1。
-
向我们展示 GetPackageById() 方法中的内容
标签: c# asp.net asp.net-mvc entity-framework entity-framework-core